135 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
import { api } from 'dicomweb-client';
 | 
						|
import dcmjs from 'dcmjs';
 | 
						|
import { calculateSUVScalingFactors } from '@cornerstonejs/calculate-suv';
 | 
						|
import { getPTImageIdInstanceMetadata } from './getPTImageIdInstanceMetadata';
 | 
						|
import { utilities } from '@cornerstonejs/core';
 | 
						|
import cornerstoneDICOMImageLoader from '@cornerstonejs/dicom-image-loader';
 | 
						|
 | 
						|
import ptScalingMetaDataProvider from './ptScalingMetaDataProvider';
 | 
						|
import getPixelSpacingInformation from './getPixelSpacingInformation';
 | 
						|
import { convertMultiframeImageIds } from './convertMultiframeImageIds';
 | 
						|
import removeInvalidTags from './removeInvalidTags';
 | 
						|
 | 
						|
const { DicomMetaDictionary } = dcmjs.data;
 | 
						|
const { calibratedPixelSpacingMetadataProvider } = utilities;
 | 
						|
 | 
						|
/**
 | 
						|
/**
 | 
						|
 * Uses dicomweb-client to fetch metadata of a study, cache it in cornerstone,
 | 
						|
 * and return a list of imageIds for the frames.
 | 
						|
 *
 | 
						|
 * Uses the app config to choose which study to fetch, and which
 | 
						|
 * dicom-web server to fetch it from.
 | 
						|
 *
 | 
						|
 * @returns {string[]} An array of imageIds for instances in the study.
 | 
						|
 */
 | 
						|
 | 
						|
export default async function createImageIdsAndCacheMetaData({
 | 
						|
  StudyInstanceUID,
 | 
						|
  SeriesInstanceUID,
 | 
						|
  SOPInstanceUID = null,
 | 
						|
  wadoRsRoot,
 | 
						|
  client = null,
 | 
						|
}) {
 | 
						|
  const SOP_INSTANCE_UID = '00080018';
 | 
						|
  const SERIES_INSTANCE_UID = '0020000E';
 | 
						|
  const MODALITY = '00080060';
 | 
						|
 | 
						|
  const studySearchOptions = {
 | 
						|
    studyInstanceUID: StudyInstanceUID,
 | 
						|
    seriesInstanceUID: SeriesInstanceUID,
 | 
						|
  };
 | 
						|
 | 
						|
  client = client || new api.DICOMwebClient({ url: wadoRsRoot });
 | 
						|
  const instances = await client.retrieveSeriesMetadata(studySearchOptions);
 | 
						|
  const modality = instances[0][MODALITY].Value[0];
 | 
						|
  let imageIds = instances.map((instanceMetaData) => {
 | 
						|
    const SeriesInstanceUID = instanceMetaData[SERIES_INSTANCE_UID].Value[0];
 | 
						|
    const SOPInstanceUIDToUse =
 | 
						|
      SOPInstanceUID || instanceMetaData[SOP_INSTANCE_UID].Value[0];
 | 
						|
 | 
						|
    const prefix = 'wadors:';
 | 
						|
 | 
						|
    const imageId =
 | 
						|
      prefix +
 | 
						|
      wadoRsRoot +
 | 
						|
      '/studies/' +
 | 
						|
      StudyInstanceUID +
 | 
						|
      '/series/' +
 | 
						|
      SeriesInstanceUID +
 | 
						|
      '/instances/' +
 | 
						|
      SOPInstanceUIDToUse +
 | 
						|
      '/frames/1';
 | 
						|
 | 
						|
    cornerstoneDICOMImageLoader.wadors.metaDataManager.add(
 | 
						|
      imageId,
 | 
						|
      instanceMetaData
 | 
						|
    );
 | 
						|
    return imageId;
 | 
						|
  });
 | 
						|
 | 
						|
  // if the image ids represent multiframe information, creates a new list with one image id per frame
 | 
						|
  // if not multiframe data available, just returns the same list given
 | 
						|
  imageIds = convertMultiframeImageIds(imageIds);
 | 
						|
 | 
						|
  imageIds.forEach((imageId) => {
 | 
						|
    let instanceMetaData =
 | 
						|
      cornerstoneDICOMImageLoader.wadors.metaDataManager.get(imageId);
 | 
						|
 | 
						|
    // It was using JSON.parse(JSON.stringify(...)) before but it is 8x slower
 | 
						|
    instanceMetaData = removeInvalidTags(instanceMetaData);
 | 
						|
 | 
						|
    if (instanceMetaData) {
 | 
						|
      // Add calibrated pixel spacing
 | 
						|
      const metadata = DicomMetaDictionary.naturalizeDataset(instanceMetaData);
 | 
						|
      const pixelSpacing = getPixelSpacingInformation(metadata);
 | 
						|
 | 
						|
      if (pixelSpacing) {
 | 
						|
        calibratedPixelSpacingMetadataProvider.add(imageId, {
 | 
						|
          rowPixelSpacing: parseFloat(pixelSpacing[0]),
 | 
						|
          columnPixelSpacing: parseFloat(pixelSpacing[1]),
 | 
						|
        });
 | 
						|
      }
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  // we don't want to add non-pet
 | 
						|
  // Note: for 99% of scanners SUV calculation is consistent bw slices
 | 
						|
  if (modality === 'PT') {
 | 
						|
    const InstanceMetadataArray = [];
 | 
						|
    imageIds.forEach((imageId) => {
 | 
						|
      const instanceMetadata = getPTImageIdInstanceMetadata(imageId);
 | 
						|
 | 
						|
      // TODO: Temporary fix because static-wado is producing a string, not an array of values
 | 
						|
      // (or maybe dcmjs isn't parsing it correctly?)
 | 
						|
      // It's showing up like 'DECY\\ATTN\\SCAT\\DTIM\\RAN\\RADL\\DCAL\\SLSENS\\NORM'
 | 
						|
      // but calculate-suv expects ['DECY', 'ATTN', ...]
 | 
						|
      if (typeof instanceMetadata.CorrectedImage === 'string') {
 | 
						|
        instanceMetadata.CorrectedImage =
 | 
						|
          instanceMetadata.CorrectedImage.split('\\');
 | 
						|
      }
 | 
						|
 | 
						|
      if (instanceMetadata) {
 | 
						|
        InstanceMetadataArray.push(instanceMetadata);
 | 
						|
      }
 | 
						|
    });
 | 
						|
    if (InstanceMetadataArray.length) {
 | 
						|
      try {
 | 
						|
        const suvScalingFactors = calculateSUVScalingFactors(
 | 
						|
          InstanceMetadataArray
 | 
						|
        );
 | 
						|
        InstanceMetadataArray.forEach((instanceMetadata, index) => {
 | 
						|
          ptScalingMetaDataProvider.addInstance(
 | 
						|
            imageIds[index],
 | 
						|
            suvScalingFactors[index]
 | 
						|
          );
 | 
						|
        });
 | 
						|
      } catch (error) {
 | 
						|
        console.log(error);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return imageIds;
 | 
						|
}
 |