Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] feat: Add key image adapters for key image point mark #1754

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
48 changes: 31 additions & 17 deletions common/reviews/api/core.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1187,6 +1187,20 @@ interface FlipDirection {
flipVertical?: boolean;
}

// @public (undocumented)
class FrameRangeUtils {
// (undocumented)
protected static frameRangeExtractor: RegExp;
// (undocumented)
protected static framesToImageId(imageId: string, range: FramesRange | string): string;
// (undocumented)
static framesToString(range: any): string;
// (undocumented)
protected static imageIdToFrames(imageId: string): FramesRange;
// (undocumented)
static multiframeImageId(imageId: string, frameNumber?: number): string;
}

// @public (undocumented)
interface GeneralSeriesModuleMetadata {
// (undocumented)
Expand Down Expand Up @@ -3415,7 +3429,7 @@ export class StackViewport extends Viewport {
// (undocumented)
getCornerstoneImage: () => IImage;
// (undocumented)
getCurrentImageId: () => string;
getCurrentImageId: (index?: number) => string;
// (undocumented)
getCurrentImageIdIndex: () => number;
// (undocumented)
Expand Down Expand Up @@ -3914,6 +3928,7 @@ function updateVTKImageDataWithCornerstoneImage(sourceImageData: vtkImageData, i

declare namespace utilities {
export {
FrameRangeUtils as frameRangeUtils,
eventListener,
invertRgbTransferFunction,
createSigmoidRGBTransferFunction,
Expand Down Expand Up @@ -4042,7 +4057,7 @@ export class VideoViewport extends Viewport {
// (undocumented)
getCamera(): ICamera;
// (undocumented)
getCurrentImageId(): string;
getCurrentImageId(index?: number): string;
// (undocumented)
getCurrentImageIdIndex(): number;
// (undocumented)
Expand Down Expand Up @@ -4329,7 +4344,7 @@ export class Viewport {
// (undocumented)
_isInBounds(point: Point3, bounds: number[]): boolean;
// (undocumented)
isReferenceViewable(viewRef: ViewReference, options?: ReferenceCompatibleOptions): boolean | unknown;
isReferenceViewable(viewRef: ViewReference, options?: ReferenceCompatibleOptions): boolean;
// (undocumented)
options: ViewportInputOptions;
// (undocumented)
Expand Down Expand Up @@ -4566,33 +4581,32 @@ interface ViewPresentationSelector {
}

// @public (undocumented)
interface ViewReference {
// (undocumented)
bounds?: BoundsLPS;
// (undocumented)
cameraFocalPoint?: Point3;
// (undocumented)
type ViewReference = {
FrameOfReferenceUID?: string;
// (undocumented)
referencedImageId?: string;
// (undocumented)
sliceIndex?: number | [number, number];
// (undocumented)
referencedImageUri?: string;
cameraFocalPoint?: Point3;
viewPlaneNormal?: Point3;
// (undocumented)
viewUp?: Point3;
// (undocumented)
sliceIndex?: number;
sliceRangeEnd?: number;
sliceSet?: Set<number>;
volumeId?: string;
}
bounds?: BoundsLPS;
};

// @public (undocumented)
interface ViewReferenceSpecifier {
// (undocumented)
forFrameOfReference?: boolean;
// (undocumented)
frameNumber?: number;
// (undocumented)
points?: Point3[];
// (undocumented)
sliceIndex?: number | [number, number];
sliceIndex?: number;
// (undocumented)
sliceRangeEnd?: number;
// (undocumented)
volumeId?: string;
}
Expand Down
21 changes: 14 additions & 7 deletions common/reviews/api/tools.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -329,18 +329,23 @@ class AnnotationFrameRange {
// (undocumented)
protected static frameRangeExtractor: RegExp;
// (undocumented)
protected static framesToImageId(imageId: string, range: FramesRange | string): string;
protected static framesToImageId(imageId: string, range: FramesRange_2 | string): string;
// (undocumented)
static framesToString(range: any): string;
// (undocumented)
static getFrameRange(annotation: Annotation): number | [number, number];
// (undocumented)
protected static imageIdToFrames(imageId: string): FramesRange;
protected static imageIdToFrames(imageId: string): FramesRange_2;
// (undocumented)
static setFrameRange(annotation: Annotation, range: FramesRange | string, eventBase?: {
viewportId: any;
renderingEngineId: any;
}): void;
static setEndRange(viewport: any, annotation: any, endRange?: any): void;
// (undocumented)
static setRange(viewport: any, annotation: any, startRange?: number, endRange?: number): void;
// (undocumented)
static setSingle(viewport: any, annotation: any, current?: any): void;
// (undocumented)
static setStartRange(viewport: any, annotation: any, startRange?: any): void;
// (undocumented)
static setViewportFrameRange(viewport: any, specifier: any): void;
}

// @public (undocumented)
Expand Down Expand Up @@ -507,7 +512,7 @@ export abstract class AnnotationTool extends AnnotationDisplayTool {
// (undocumented)
static createAnnotation(...annotationBaseData: any[]): Annotation;
// (undocumented)
static createAnnotationForViewport(viewport: any, ...annotationBaseData: any[]): Annotation;
static createAnnotationForViewport<T extends Annotation>(viewport: any, ...annotationBaseData: any[]): T;
// (undocumented)
static createAnnotationMemo(element: any, annotation: Annotation, options?: {
newAnnotation?: boolean;
Expand Down Expand Up @@ -980,6 +985,8 @@ enum ChangeTypes {
// (undocumented)
InterpolationUpdated = "InterpolationUpdated",
// (undocumented)
MetadataReferenceModified = "MetadataReferenceModified",
// (undocumented)
StatsUpdated = "StatsUpdated"
}

Expand Down
89 changes: 89 additions & 0 deletions packages/adapters/src/adapters/Cornerstone3D/BaseAdapter3D.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import CORNERSTONE_3D_TAG from "./cornerstone3DTag";
import MeasurementReport from "./MeasurementReport";

/**
* This is a basic definition of adapters to be inherited for other adapters.
*/
export default class BaseAdapter3D {
public static toolType: string;
public static utilityToolType: string;
public static TID300Representation;
public static trackingIdentifierTextValue: string;

/**
* @returns true if the tool is of the given tool type based on the tracking identifier
*/
public static isValidCornerstoneTrackingIdentifier = trackingIdentifier => {
if (!trackingIdentifier.includes(":")) {
return false;
}

const [cornerstone3DTag, toolType] = trackingIdentifier.split(":");

if (cornerstone3DTag !== CORNERSTONE_3D_TAG) {
return false;
}

return toolType === this.toolType;
};

/**
* Returns annotation data for CS3D to use based on the underlying
* DICOM SR annotation data.
*/
public static getMeasurementData(
MeasurementGroup,
sopInstanceUIDToImageIdMap,
_imageToWorldCoords,
metadata
) {
const { defaultState: state, ReferencedFrameNumber } =
MeasurementReport.getSetupMeasurementData(
MeasurementGroup,
sopInstanceUIDToImageIdMap,
metadata,
this.toolType
);

state.annotation.data = {
cachedStats: {},
frameNumber: ReferencedFrameNumber
};

return state;
}

public static getTID300RepresentationArguments(
tool,
worldToImageCoords
): Record<string, unknown> {
const { data, metadata } = tool;
const { finding, findingSites } = tool;
const { referencedImageId } = metadata;

if (!referencedImageId) {
throw new Error(
"Probe.getTID300RepresentationArguments: referencedImageId is not defined"
);
}

const { points } = data.handles;

const pointsImage = points.map(point => {
const pointImage = worldToImageCoords(referencedImageId, point);
return {
x: pointImage[0],
y: pointImage[1]
};
});

const TID300RepresentationArguments = {
points: pointsImage,
trackingIdentifierTextValue: this.trackingIdentifierTextValue,
findingSites: findingSites || [],
finding
};

return TID300RepresentationArguments;
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import { utilities } from "dcmjs";
import CORNERSTONE_3D_TAG from "./cornerstone3DTag";
import MeasurementReport from "./MeasurementReport";
import BaseAdapter3D from "./BaseAdapter3D";

const { Length: TID300Length } = utilities.TID300;

const LENGTH = "Length";
const trackingIdentifierTextValue = `${CORNERSTONE_3D_TAG}:${LENGTH}`;

class Length {
export default class Length extends BaseAdapter3D {
public static toolType = LENGTH;
public static utilityToolType = LENGTH;
public static TID300Representation = TID300Length;
public static trackingIdentifierTextValue = `${CORNERSTONE_3D_TAG}:${LENGTH}`;

// TODO: this function is required for all Cornerstone Tool Adapters, since it is called by MeasurementReport.
static getMeasurementData(
MeasurementGroup,
Expand All @@ -20,7 +25,7 @@ class Length {
MeasurementGroup,
sopInstanceUIDToImageIdMap,
metadata,
Length.toolType
this.toolType
);

const referencedImageId =
Expand Down Expand Up @@ -84,30 +89,11 @@ class Length {
point1,
point2,
distance,
trackingIdentifierTextValue,
trackingIdentifierTextValue: this.trackingIdentifierTextValue,
finding,
findingSites: findingSites || []
};
}
}

Length.toolType = LENGTH;
Length.utilityToolType = LENGTH;
Length.TID300Representation = TID300Length;
Length.isValidCornerstoneTrackingIdentifier = TrackingIdentifier => {
if (!TrackingIdentifier.includes(":")) {
return false;
}

const [cornerstone3DTag, toolType] = TrackingIdentifier.split(":");

if (cornerstone3DTag !== CORNERSTONE_3D_TAG) {
return false;
}

return toolType === LENGTH;
};

MeasurementReport.registerTool(Length);

export default Length;
Loading
Loading