All files / extensions/cornerstone/src/utils setUpSegmentationEventHandlers.ts

96.66% Statements 29/30
80% Branches 8/10
100% Functions 3/3
96.66% Lines 29/30

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123                204x   204x     204x           204x       204x     141x 141x 141x 81x     60x 60x   60x       60x                                 60x       204x     16x     16x                     13x   13x         13x 13x     13x 28x 28x                   13x 3x             204x       204x               204x    
import { Enums as csToolsEnums } from '@cornerstonejs/tools';
 
import {
  setUpSelectedSegmentationsForViewportHandler,
  setupSegmentationDataModifiedHandler,
  setupSegmentationModifiedHandler,
} from './segmentationHandlers';
 
export const setUpSegmentationEventHandlers = ({ servicesManager, commandsManager }) => {
  const { segmentationService, customizationService, displaySetService, viewportGridService } =
    servicesManager.services;
 
  const { unsubscribe: unsubscribeSegmentationDataModifiedHandler } =
    setupSegmentationDataModifiedHandler({
      segmentationService,
      customizationService,
      commandsManager,
    });
 
  const { unsubscribe: unsubscribeSegmentationModifiedHandler } = setupSegmentationModifiedHandler({
    segmentationService,
  });
 
  const { unsubscribe: unsubscribeSegmentationCreated } = segmentationService.subscribe(
    segmentationService.EVENTS.SEGMENTATION_ADDED,
    evt => {
      const { segmentationId } = evt;
      const displaySet = displaySetService.getDisplaySetByUID(segmentationId);
      if (displaySet) {
        return;
      }
 
      const segmentation = segmentationService.getSegmentation(segmentationId);
      const label = segmentation.label;
      const imageIds =
        segmentation.representationData?.Labelmap?.imageIds ??
        segmentation.representationData?.Contour?.imageIds;
 
      // Create a display set for the segmentation
      const segmentationDisplaySet = {
        displaySetInstanceUID: segmentationId,
        SOPClassUID: '1.2.840.10008.5.1.4.1.1.66.4',
        SOPClassHandlerId: '@ohif/extension-cornerstone-dicom-seg.sopClassHandlerModule.dicom-seg',
        SeriesDescription: label,
        Modality: segmentation.representationData[csToolsEnums.SegmentationRepresentations.Contour]
          ? 'RTSTRUCT'
          : 'SEG',
        numImageFrames: imageIds.length,
        imageIds,
        isOverlayDisplaySet: true,
        label,
        madeInClient: true,
        segmentationId: segmentationId,
        isDerived: true,
      };
 
      displaySetService.addDisplaySets(segmentationDisplaySet);
    }
  );
 
  const { unsubscribe: unsubscribeSegmentationRemoved } = segmentationService.subscribe(
    segmentationService.EVENTS.SEGMENTATION_REMOVED,
    ({ segmentationId }) => {
      const displaySet = displaySetService.getDisplaySetByUID(segmentationId);
 
      // Remove the display set layer from all viewports that have it
      if (displaySet) {
        // This is the global removal path (the segmentation is gone from state,
        // e.g. deleted from the segmentation panel), so clear the global
        // "show this wherever it logically belongs" state. It must happen
        // outside the loop below: that loop only visits viewports carrying the
        // segmentation as an explicit layer, and a hydrated segmentation is
        // never listed in a viewport's displaySetInstanceUIDs - only the
        // referenced volume is. Recording `hydrated: false` rather than just
        // dropping the entry keeps the store a statement of desired state, so a
        // viewport created later converges on "not shown" instead of replaying
        // an earlier `hydrated: true`.
        displaySet.isHydrated = false;
 
        commandsManager.runCommand('updateStoredSegmentationPresentation', {
          displaySet,
          hydrated: false,
        });
 
        const state = viewportGridService.getState();
        const viewports = state.viewports;
 
        // Find all viewports that contain this segmentation's display set as a layer
        for (const [viewportId, viewport] of viewports.entries()) {
          const displaySetInstanceUIDs = viewport.displaySetInstanceUIDs || [];
          Iif (displaySetInstanceUIDs.includes(segmentationId)) {
            // Remove the display set layer from this viewport
            commandsManager.runCommand('removeDisplaySetLayer', {
              viewportId,
              displaySetInstanceUID: segmentationId,
            });
          }
        }
 
        // Delete the display set from the service if it was made in client
        if (displaySet.madeInClient) {
          displaySetService.deleteDisplaySet(segmentationId);
        }
      }
    }
  );
 
  const { unsubscribeSelectedSegmentationsForViewportEvents } =
    setUpSelectedSegmentationsForViewportHandler({
      segmentationService,
    });
 
  const unsubscriptions = [
    unsubscribeSegmentationDataModifiedHandler,
    unsubscribeSegmentationModifiedHandler,
    unsubscribeSegmentationCreated,
    unsubscribeSegmentationRemoved,
    ...unsubscribeSelectedSegmentationsForViewportEvents,
  ];
 
  return { unsubscriptions };
};