@bettermedicine/imeasure 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,15 @@
1
1
  import { TInteractiveIMeasureModeClicks } from "../types/io";
2
2
  import { TWorldMetadata, TCropMetadata } from "../types/metadata";
3
+ /**
4
+ * @internal
5
+ * TODO: interactive docs
6
+ */
3
7
  export type TInteractiveImeasureInput = {
4
8
  id: string;
5
9
  clicks: TInteractiveIMeasureModeClicks[];
6
10
  } & TWorldMetadata & TCropMetadata;
11
+ /**
12
+ * @internal
13
+ * TODO: interactive docs
14
+ */
7
15
  export declare const formatInteractivePayload: (input: TInteractiveImeasureInput, image: Int16Array, mask?: Uint8Array) => import("undici-types").FormData;
@@ -1,4 +1,8 @@
1
1
  import { vec3ToPoint3D } from "./utils";
2
+ /**
3
+ * @internal
4
+ * TODO: interactive docs
5
+ */
2
6
  export const formatInteractivePayload = (input, image, mask) => {
3
7
  const fd = new FormData();
4
8
  const metadata = {
@@ -1,26 +1,121 @@
1
1
  import { Point3D } from "./cornerstone";
2
+ /**
3
+ * Represents a raw measurement between two points in both voxel and world spaces.
4
+ *
5
+ * @property coords_voxel - The start and end points of the measurement in voxel-space coordinates.
6
+ * @property coords_world - The start and end points of the measurement in world-space coordinates.
7
+ * @property length_voxel - The distance between the two points in voxel space.
8
+ * @property length_world - The distance between the two points in world space.
9
+ */
2
10
  export type TRawMeasurement = {
3
11
  coords_voxel: [Point3D, Point3D];
4
12
  coords_world: [Point3D, Point3D];
5
13
  length_voxel: number;
6
14
  length_world: number;
7
15
  };
16
+ /**
17
+ * Represents a cross measurement consisting of two raw measurements.
18
+ *
19
+ * @property short - The shorter measurement in the cross.
20
+ * @property long - The longer measurement in the cross.
21
+ */
8
22
  export type TCrossMeasurement = {
9
23
  short: TRawMeasurement;
10
24
  long: TRawMeasurement;
11
25
  };
26
+ /**
27
+ * Represents a collection of measurements derived from the resulting segmentation mask.
28
+ *
29
+ * @property cross - Contains measurements for the cross section, with the key "2" representing the axial plane.
30
+ * @property diagonal - Represents the diagonal measurement.
31
+ * @property height - Represents the height measurement.
32
+ * @privateRemarks
33
+ * the key of "2" should be replaced with a more descriptive name in the future, eg. "axial"
34
+ */
35
+ export type TMeasurements = {
36
+ cross: {
37
+ 2: TCrossMeasurement;
38
+ };
39
+ diagonal: TRawMeasurement;
40
+ height: TRawMeasurement;
41
+ };
42
+ /**
43
+ * The return type of the static IMeasure 3D API endpoint.
44
+ *
45
+ * @property mask - A base64-encoded string that represents the flattened 3D segmentation mask.
46
+ * The mask is a binary representation of the segmentation, with `0` representing background voxels and `1` representing foreground voxels.
47
+ * To marshal it into a 3D mask, the client should convert the base64 string into an array of numbers and reshape it
48
+ * to conform to the returned `mask_shape` property.
49
+ * @property measurements - An object containing cross, diagonal, and height measurements.
50
+ * @property volume_mm3 - The volume of the segmentation in cubic millimeters.
51
+ * @property volume - The volume of the segmentation in voxels.
52
+ * @property mask_shape - The shape of the mask in voxels, represented as a tuple of three integers (x, y, z).
53
+ * @property mask_spacing - The world-space spacing of the mask in voxel coordinates, represented as a tuple of three floats (x, y, z).
54
+ * @property mask_origin_voxel - The origin of the mask in voxel coordinates, represented as a tuple of three integers (x, y, z).
55
+ *
56
+ * @interface
57
+ */
12
58
  export type TIMeasure3DResponse = {
13
59
  mask: string;
14
- measurements: {
15
- cross: {
16
- 0: TCrossMeasurement;
17
- 1: TCrossMeasurement;
18
- 2: TCrossMeasurement;
19
- };
20
- diagonal: TRawMeasurement;
21
- height: TRawMeasurement;
22
- };
60
+ measurements: TMeasurements;
61
+ volume_mm3: number;
62
+ volume: number;
63
+ mask_shape: [number, number, number];
64
+ mask_spacing: Point3D;
65
+ mask_origin_voxel: Point3D;
23
66
  };
67
+ /**
68
+ * The generic input type for the `metadata` part of an iMeasure request, expended by the default Static and experimental
69
+ * Interactive iMeasure variants.
70
+ *
71
+ * This type is used to define the metadata that is sent along with the iMeasure request and should be included
72
+ * in the multipart FormData request body as a `Blob`:
73
+ * ```typescript
74
+ * const formData = new FormData();
75
+ * formData.append("metadata", new Blob([JSON.stringify(metadata)], { type: "application/json" }));
76
+ * ```
77
+ *
78
+ * @see the function {@link metadata.extractWorldMetaFromImageDataAndDisplaySet | extractWorldMetaFromImageDataAndDisplaySet} for deriving the following properties from a VTK volume and an OHIF displayset:
79
+ * - * `worldOrigin`
80
+ * - * `worldShape`
81
+ * - * `worldSpacing`
82
+ * - * `worldBoundingImagePositions`
83
+ * - * `imageCount`
84
+ * - * `rescaleIntercept`
85
+ * - * `rescaleSlope`
86
+ * - * `imageOrientationPatient`
87
+ * @see the function {@link math.cropping.calculateStaticImeasureBoundingBox | calculateStaticImeasureBoundingBox} in for deriving the following properties from user clicks and world affines:
88
+ * - * `cropBoundariesWorld`
89
+ * - * `cropBoundariesVoxel`
90
+ * - * `cropBoundariesUnclippedVoxel`
91
+ * - * `cropCuboidCenterVoxel`
92
+ * - * `shape`
93
+ *
94
+ * @see the {@link formatting.formatStaticPayload | formatStaticPayload} function for an utility function for constructing the FormData
95
+ * payload from an union of {@link Types.Metadata.TWorldMetadata | TWorldMetadata}, {@link Types.Metadata.TCropMetadata | TCropMetadata} and parsed image data.
96
+ *
97
+ * @property id - A unique UUID4-compliant identifier for the measurement.
98
+ * @property world_origin - The origin of the world coordinate system in world-space, represented as a tuple of three floats (x, y, z).
99
+ * @property world_shape - The shape of the world voxel space, represented as a tuple of three integers (x, y, z) - eg. [512, 512, 100].
100
+ * @property world_spacing - The spacing of the world voxel space, represented as a tuple of three floats (x, y, z).
101
+ * @property rescale_intercept - The rescale intercept value for the underlying series, used to adjust/normalize pixel values.
102
+ * @property rescale_slope - The rescale slope value for the underlying series, used to adjust/normalize pixel values.
103
+ * @property image_orientation_patient - The image orientation in patient coordinates, represented as a tuple of six floats
104
+ * (x1, y1, z1, x2, y2, z2), where (x1, y1, z1) and (x2, y2, z2) are the direction cosines of the image axes.
105
+ * @property crop_boundaries_world - The boundaries of the crop region in world coordinates, represented as a tuple of two Point3D objects
106
+ * (minPoint, maxPoint), where minPoint and maxPoint are the minimum and maximum points of the crop region in world space.
107
+ * @property crop_boundaries_voxel - The boundaries of the crop region in voxel coordinates, represented as a tuple of two Point3D objects
108
+ * (minPoint, maxPoint), where minPoint and maxPoint are the minimum and maximum points of the crop region in voxel space.
109
+ * @property crop_boundaries_unclipped_voxel - The unclipped boundaries of the crop region in voxel coordinates,
110
+ * represented as a tuple of two Point3D objects (minPoint, maxPoint),
111
+ * where minPoint and maxPoint are the minimum and maximum points of the crop region in voxel space before clipping.
112
+ * @property crop_cuboid_center_voxel - The center of the crop cuboid in voxel coordinates, represented as a
113
+ * Point3D object (x, y, z), where (x, y, z) are the coordinates of the center point of the crop cuboid in voxel space before clipping.
114
+ * @property shape - The shape of the cropped volume, represented as a tuple of three integers (x, y, z).
115
+ * @property world_bounding_image_positions - Effectively the ImagePositionPatient values for the first and last images in the series,
116
+ * represented as a tuple of two Point3D objects (firstPosition, lastPosition).
117
+ * @property image_count - The number of images in the entire series.
118
+ */
24
119
  export type TIMeasure3DGenericPayload = {
25
120
  id: string;
26
121
  world_origin: Point3D;
@@ -37,15 +132,35 @@ export type TIMeasure3DGenericPayload = {
37
132
  world_bounding_image_positions: [Point3D, Point3D];
38
133
  image_count: number;
39
134
  };
40
- export type TStaticImeasurePayload = TIMeasure3DGenericPayload & {
135
+ /**
136
+ * The shape of the payload for static iMeasure operations.
137
+ *
138
+ * @remarks
139
+ * This type extends {@link TIMeasure3DGenericPayload}, inheriting all its properties,
140
+ * and adds a `clicks` property representing two 3D points.
141
+ *
142
+ * @property clicks - A tuple containing two {@link Point3D} objects, representing the selected points in 3D space.
143
+ *
144
+ * @see {@link TIMeasure3DGenericPayload} for inherited properties and additional context.
145
+ */
146
+ export interface IStaticIMeasurePayload extends TIMeasure3DGenericPayload {
41
147
  clicks: [Point3D, Point3D];
42
- };
148
+ }
149
+ /**
150
+ * @internal
151
+ */
43
152
  export type TInteractiveIMeasureMode = "positive" | "negative";
153
+ /**
154
+ * @internal
155
+ */
44
156
  export type TInteractiveIMeasureModeClicks = {
45
157
  mode: TInteractiveIMeasureMode;
46
158
  points: Point3D[];
47
159
  firstClick?: true;
48
160
  };
161
+ /**
162
+ * @internal
163
+ */
49
164
  export type TInteractiveImeasurePayload = TIMeasure3DGenericPayload & {
50
165
  finding_id?: string;
51
166
  clicks: TInteractiveIMeasureModeClicks[];
@@ -126,6 +126,7 @@ const config: Config = {
126
126
  sidebar: {
127
127
  autoConfiguration: false,
128
128
  },
129
+ excludeInternal: true,
129
130
  },
130
131
  ],
131
132
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bettermedicine/imeasure",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "main": "dist/index.js",
5
5
  "scripts": {
6
6
  "prepack": "npm run build",
@@ -5,12 +5,19 @@ import {
5
5
  import { TWorldMetadata, TCropMetadata } from "../types/metadata";
6
6
  import { vec3ToPoint3D } from "./utils";
7
7
 
8
+ /**
9
+ * @internal
10
+ * TODO: interactive docs
11
+ */
8
12
  export type TInteractiveImeasureInput = {
9
13
  id: string;
10
14
  clicks: TInteractiveIMeasureModeClicks[];
11
15
  } & TWorldMetadata &
12
16
  TCropMetadata;
13
-
17
+ /**
18
+ * @internal
19
+ * TODO: interactive docs
20
+ */
14
21
  export const formatInteractivePayload = (
15
22
  input: TInteractiveImeasureInput,
16
23
  image: Int16Array,
@@ -1,5 +1,5 @@
1
1
  import { Point3D } from "../types/cornerstone";
2
- import { TStaticImeasurePayload } from "../types/io";
2
+ import { IStaticIMeasurePayload } from "../types/io";
3
3
  import { TWorldMetadata, TCropMetadata } from "../types/metadata";
4
4
  import { vec3ToPoint3D } from "./utils";
5
5
 
@@ -14,7 +14,7 @@ export const formatStaticPayload = (
14
14
  image: Int16Array
15
15
  ) => {
16
16
  const fd = new FormData();
17
- const metadata: TStaticImeasurePayload = {
17
+ const metadata: IStaticIMeasurePayload = {
18
18
  id: input.id,
19
19
  clicks: input.clicks,
20
20
  world_origin: vec3ToPoint3D(input.worldOrigin),
package/src/types/io.ts CHANGED
@@ -1,5 +1,13 @@
1
1
  import { Point3D } from "./cornerstone";
2
2
 
3
+ /**
4
+ * Represents a raw measurement between two points in both voxel and world spaces.
5
+ *
6
+ * @property coords_voxel - The start and end points of the measurement in voxel-space coordinates.
7
+ * @property coords_world - The start and end points of the measurement in world-space coordinates.
8
+ * @property length_voxel - The distance between the two points in voxel space.
9
+ * @property length_world - The distance between the two points in world space.
10
+ */
3
11
  export type TRawMeasurement = {
4
12
  coords_voxel: [Point3D, Point3D];
5
13
  coords_world: [Point3D, Point3D];
@@ -7,26 +15,115 @@ export type TRawMeasurement = {
7
15
  length_world: number;
8
16
  };
9
17
 
18
+ /**
19
+ * Represents a cross measurement consisting of two raw measurements.
20
+ *
21
+ * @property short - The shorter measurement in the cross.
22
+ * @property long - The longer measurement in the cross.
23
+ */
10
24
  export type TCrossMeasurement = {
11
25
  short: TRawMeasurement;
12
26
  long: TRawMeasurement;
13
27
  };
14
28
 
15
- export type TIMeasure3DResponse = {
16
- mask: string; // a base64-encoded string that represents the mask
17
- measurements: {
18
- cross: {
19
- // TODO: make this an array
20
- 0: TCrossMeasurement;
21
- 1: TCrossMeasurement;
22
- 2: TCrossMeasurement; // this could be the only relevant one as it is in "axial" orientation
23
- };
24
- diagonal: TRawMeasurement;
25
- height: TRawMeasurement;
29
+ /**
30
+ * Represents a collection of measurements derived from the resulting segmentation mask.
31
+ *
32
+ * @property cross - Contains measurements for the cross section, with the key "2" representing the axial plane.
33
+ * @property diagonal - Represents the diagonal measurement.
34
+ * @property height - Represents the height measurement.
35
+ * @privateRemarks
36
+ * the key of "2" should be replaced with a more descriptive name in the future, eg. "axial"
37
+ */
38
+
39
+ export type TMeasurements = {
40
+ cross: {
41
+ 2: TCrossMeasurement;
26
42
  };
43
+ diagonal: TRawMeasurement;
44
+ height: TRawMeasurement;
27
45
  };
28
46
 
29
- // Shared generics
47
+ /**
48
+ * The return type of the static IMeasure 3D API endpoint.
49
+ *
50
+ * @property mask - A base64-encoded string that represents the flattened 3D segmentation mask.
51
+ * The mask is a binary representation of the segmentation, with `0` representing background voxels and `1` representing foreground voxels.
52
+ * To marshal it into a 3D mask, the client should convert the base64 string into an array of numbers and reshape it
53
+ * to conform to the returned `mask_shape` property.
54
+ * @property measurements - An object containing cross, diagonal, and height measurements.
55
+ * @property volume_mm3 - The volume of the segmentation in cubic millimeters.
56
+ * @property volume - The volume of the segmentation in voxels.
57
+ * @property mask_shape - The shape of the mask in voxels, represented as a tuple of three integers (x, y, z).
58
+ * @property mask_spacing - The world-space spacing of the mask in voxel coordinates, represented as a tuple of three floats (x, y, z).
59
+ * @property mask_origin_voxel - The origin of the mask in voxel coordinates, represented as a tuple of three integers (x, y, z).
60
+ *
61
+ * @interface
62
+ */
63
+
64
+ export type TIMeasure3DResponse = {
65
+ mask: string;
66
+ measurements: TMeasurements;
67
+ volume_mm3: number;
68
+ volume: number;
69
+ mask_shape: [number, number, number];
70
+ mask_spacing: Point3D;
71
+ mask_origin_voxel: Point3D;
72
+ };
73
+
74
+ /**
75
+ * The generic input type for the `metadata` part of an iMeasure request, expended by the default Static and experimental
76
+ * Interactive iMeasure variants.
77
+ *
78
+ * This type is used to define the metadata that is sent along with the iMeasure request and should be included
79
+ * in the multipart FormData request body as a `Blob`:
80
+ * ```typescript
81
+ * const formData = new FormData();
82
+ * formData.append("metadata", new Blob([JSON.stringify(metadata)], { type: "application/json" }));
83
+ * ```
84
+ *
85
+ * @see the function {@link metadata.extractWorldMetaFromImageDataAndDisplaySet | extractWorldMetaFromImageDataAndDisplaySet} for deriving the following properties from a VTK volume and an OHIF displayset:
86
+ * - * `worldOrigin`
87
+ * - * `worldShape`
88
+ * - * `worldSpacing`
89
+ * - * `worldBoundingImagePositions`
90
+ * - * `imageCount`
91
+ * - * `rescaleIntercept`
92
+ * - * `rescaleSlope`
93
+ * - * `imageOrientationPatient`
94
+ * @see the function {@link math.cropping.calculateStaticImeasureBoundingBox | calculateStaticImeasureBoundingBox} in for deriving the following properties from user clicks and world affines:
95
+ * - * `cropBoundariesWorld`
96
+ * - * `cropBoundariesVoxel`
97
+ * - * `cropBoundariesUnclippedVoxel`
98
+ * - * `cropCuboidCenterVoxel`
99
+ * - * `shape`
100
+ *
101
+ * @see the {@link formatting.formatStaticPayload | formatStaticPayload} function for an utility function for constructing the FormData
102
+ * payload from an union of {@link Types.Metadata.TWorldMetadata | TWorldMetadata}, {@link Types.Metadata.TCropMetadata | TCropMetadata} and parsed image data.
103
+ *
104
+ * @property id - A unique UUID4-compliant identifier for the measurement.
105
+ * @property world_origin - The origin of the world coordinate system in world-space, represented as a tuple of three floats (x, y, z).
106
+ * @property world_shape - The shape of the world voxel space, represented as a tuple of three integers (x, y, z) - eg. [512, 512, 100].
107
+ * @property world_spacing - The spacing of the world voxel space, represented as a tuple of three floats (x, y, z).
108
+ * @property rescale_intercept - The rescale intercept value for the underlying series, used to adjust/normalize pixel values.
109
+ * @property rescale_slope - The rescale slope value for the underlying series, used to adjust/normalize pixel values.
110
+ * @property image_orientation_patient - The image orientation in patient coordinates, represented as a tuple of six floats
111
+ * (x1, y1, z1, x2, y2, z2), where (x1, y1, z1) and (x2, y2, z2) are the direction cosines of the image axes.
112
+ * @property crop_boundaries_world - The boundaries of the crop region in world coordinates, represented as a tuple of two Point3D objects
113
+ * (minPoint, maxPoint), where minPoint and maxPoint are the minimum and maximum points of the crop region in world space.
114
+ * @property crop_boundaries_voxel - The boundaries of the crop region in voxel coordinates, represented as a tuple of two Point3D objects
115
+ * (minPoint, maxPoint), where minPoint and maxPoint are the minimum and maximum points of the crop region in voxel space.
116
+ * @property crop_boundaries_unclipped_voxel - The unclipped boundaries of the crop region in voxel coordinates,
117
+ * represented as a tuple of two Point3D objects (minPoint, maxPoint),
118
+ * where minPoint and maxPoint are the minimum and maximum points of the crop region in voxel space before clipping.
119
+ * @property crop_cuboid_center_voxel - The center of the crop cuboid in voxel coordinates, represented as a
120
+ * Point3D object (x, y, z), where (x, y, z) are the coordinates of the center point of the crop cuboid in voxel space before clipping.
121
+ * @property shape - The shape of the cropped volume, represented as a tuple of three integers (x, y, z).
122
+ * @property world_bounding_image_positions - Effectively the ImagePositionPatient values for the first and last images in the series,
123
+ * represented as a tuple of two Point3D objects (firstPosition, lastPosition).
124
+ * @property image_count - The number of images in the entire series.
125
+ */
126
+
30
127
  export type TIMeasure3DGenericPayload = {
31
128
  id: string;
32
129
  world_origin: Point3D;
@@ -44,18 +141,40 @@ export type TIMeasure3DGenericPayload = {
44
141
  image_count: number;
45
142
  };
46
143
 
47
- export type TStaticImeasurePayload = TIMeasure3DGenericPayload & {
144
+ /**
145
+ * The shape of the payload for static iMeasure operations.
146
+ *
147
+ * @remarks
148
+ * This type extends {@link TIMeasure3DGenericPayload}, inheriting all its properties,
149
+ * and adds a `clicks` property representing two 3D points.
150
+ *
151
+ * @property clicks - A tuple containing two {@link Point3D} objects, representing the selected points in 3D space.
152
+ *
153
+ * @see {@link TIMeasure3DGenericPayload} for inherited properties and additional context.
154
+ */
155
+ export interface IStaticIMeasurePayload extends TIMeasure3DGenericPayload {
48
156
  clicks: [Point3D, Point3D];
49
- };
157
+ }
158
+
159
+ // TODO: better docs from this point onwards - marked as internal for now to not include
160
+ // them in the docs.
50
161
 
51
- // interactive input and payload types
162
+ /**
163
+ * @internal
164
+ */
52
165
  export type TInteractiveIMeasureMode = "positive" | "negative";
166
+ /**
167
+ * @internal
168
+ */
53
169
  export type TInteractiveIMeasureModeClicks = {
54
170
  mode: TInteractiveIMeasureMode;
55
171
  points: Point3D[];
56
172
  firstClick?: true;
57
173
  };
58
174
 
175
+ /**
176
+ * @internal
177
+ */
59
178
  export type TInteractiveImeasurePayload = TIMeasure3DGenericPayload & {
60
179
  finding_id?: string;
61
180
  clicks: TInteractiveIMeasureModeClicks[];