Skip to content

Commit

Permalink
feat: new Total Metabolic Tumor Volume tmtv (#2866)
Browse files Browse the repository at this point in the history
* fix: ptDisplaySet metadata problem

* fix: typo in xhrHeader field

* fix: temporary fix for crosshairs on reload data

* fix hotkey bug for input fields

* upgrade docusarusu to stable release

* circle ci node upgrade

* cypress node upgrade

* bump node in netlify

* bump node version

* remove versioned docs

* update resources

* fix: webpack injection of plugins

* fix meaningful label for panels

* add reviews and fix cli for creation

* copy over chunks if exists in the build

* edit templates

* edit templates

* fix yarn lock

* fix(plugin):Deploy on windows is broken

Co-authored-by: Bill Wallace <[email protected]>
  • Loading branch information
sedghi and wayfarer3130 authored Aug 17, 2022
1 parent ae897c4 commit 10b4ed5
Show file tree
Hide file tree
Showing 41 changed files with 2,033 additions and 824 deletions.
12 changes: 6 additions & 6 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ executors:
# Custom executor to override Cypress config
deploy-to-prod-executor:
docker:
- image: cimg/node:14.18
- image: cimg/node:16.14
environment:
CYPRESS_BASE_URL: https://ohif-staging.netlify.com/
chrome-and-pacs:
docker:
# Primary container image where all steps run.
- image: 'cypress/browsers:node14.17.0-chrome88-ff89'
- image: 'cypress/browsers:node16.14.2-slim-chrome103-ff102'

defaults: &defaults
docker:
- image: cimg/node:14.18-browsers
- image: cimg/node:16.14-browsers
environment:
TERM: xterm # Enable colors in term
QUICK_BUILD: true
Expand Down Expand Up @@ -181,7 +181,7 @@ jobs:

DEPLOY_TO_DEV:
docker:
- image: circleci/node:14.17.0
- image: circleci/node:16.14.0
environment:
TERM: xterm
NETLIFY_SITE_ID: 32708787-c9b0-4634-b50f-7ca41952da77
Expand All @@ -196,7 +196,7 @@ jobs:

DEPLOY_TO_STAGING:
docker:
- image: circleci/node:14.17.0
- image: circleci/node:16.14.0
environment:
TERM: xterm
NETLIFY_SITE_ID: c7502ae3-b150-493c-8422-05701e44a969
Expand All @@ -211,7 +211,7 @@ jobs:

DEPLOY_TO_PRODUCTION:
docker:
- image: circleci/node:14.17.0
- image: circleci/node:16.14.0
environment:
TERM: xterm
NETLIFY_SITE_ID: 79c4a5da-5c95-4dc9-84f7-45fd9dfe21b0
Expand Down
2 changes: 1 addition & 1 deletion .node-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
14.18.0
16.14.0
3 changes: 2 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"proseWrap": "always",
"tabWidth": 2,
"semi": true,
"singleQuote": true
"singleQuote": true,
"arrowParens": "avoid"
}
4 changes: 2 additions & 2 deletions extensions/cornerstone-dicom-sr/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"dependencies": {
"@babel/runtime": "7.16.3",
"classnames": "^2.2.6",
"@cornerstonejs/core": "^0.13.11",
"@cornerstonejs/tools": "^0.20.15"
"@cornerstonejs/core": "^0.14.4",
"@cornerstonejs/tools": "^0.21.7"
}
}
8 changes: 4 additions & 4 deletions extensions/cornerstone/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"peerDependencies": {
"@ohif/core": "^3.0.0",
"@ohif/ui": "^2.0.0",
"cornerstone-wado-image-loader": "^4.2.0",
"cornerstone-wado-image-loader": "^4.2.1",
"dcmjs": "^0.24.5",
"dicom-parser": "^1.8.9",
"hammerjs": "^2.0.8",
Expand All @@ -43,9 +43,9 @@
},
"dependencies": {
"@babel/runtime": "7.17.9",
"@cornerstonejs/core": "^0.13.11",
"@cornerstonejs/streaming-image-volume-loader": "^0.4.10",
"@cornerstonejs/tools": "^0.20.15",
"@cornerstonejs/core": "^0.14.4",
"@cornerstonejs/streaming-image-volume-loader": "^0.4.16",
"@cornerstonejs/tools": "^0.21.7",
"@kitware/vtk.js": "^24.18.7",
"dom-to-image": "^2.6.0",
"lodash.debounce": "4.0.8",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,11 @@ const OHIFCornerstoneViewport = React.memo(props => {
DisplaySetService
);

const keepCamera = true;
CornerstoneViewportService.updateViewport(
viewportIndex,
newViewportData
newViewportData,
keepCamera
);

setViewportData(newViewportData);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function CornerstoneOverlays(props) {
viewportIndex
);

if (viewportInfo?.viewportOptions?.customViewportOptions?.hideOverlays) {
if (viewportInfo?.viewportOptions?.customViewportProps?.hideOverlays) {
return null;
}
}
Expand Down
23 changes: 11 additions & 12 deletions extensions/cornerstone/src/commandsModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,19 +115,18 @@ const commandsModule = ({ servicesManager }) => {
const renderingEngine = CornerstoneViewportService.getRenderingEngine();
const viewport = renderingEngine.getViewport(viewportId);

const lower = windowCenterNum - windowWidthNum / 2.0;
const upper = windowCenterNum + windowWidthNum / 2.0;

if (viewport instanceof StackViewport) {
viewport.setProperties({
voiRange: {
upper,
lower,
},
});
const { lower, upper } = csUtils.windowLevel.toLowHighRange(
windowWidthNum,
windowCenterNum
);

viewport.render();
}
viewport.setProperties({
voiRange: {
upper,
lower,
},
});
viewport.render();
},
toggleCrosshairs({ toolGroupId, toggledState }) {
const toolName = 'Crosshairs';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,14 +166,12 @@ class CornerstoneViewportService implements IViewportService {
const viewportInfo = this.viewportsInfo.get(viewportIndex);
viewportInfo.setRenderingEngineId(renderingEngine.id);

const {
viewportOptions,
displaySetOptions,
} = this._getViewportAndDisplaySetOptions(
publicViewportOptions,
publicDisplaySetOptions,
viewportInfo
);
const { viewportOptions, displaySetOptions } =
this._getViewportAndDisplaySetOptions(
publicViewportOptions,
publicDisplaySetOptions,
viewportInfo
);

viewportInfo.setViewportOptions(viewportOptions);
viewportInfo.setDisplaySetOptions(displaySetOptions);
Expand Down Expand Up @@ -400,48 +398,57 @@ class CornerstoneViewportService implements IViewportService {
volume.load();
});

this.setVolumesForViewport(viewport, volumeInputArray);
// This returns the async continuation only
return this.setVolumesForViewport(viewport, volumeInputArray);
}

public setVolumesForViewport(viewport, volumeInputArray) {
viewport.setVolumes(volumeInputArray).then(() => {
const viewportInfo = this.getViewportInfo(viewport.id);
const initialImageOptions = viewportInfo.getInitialImageOptions();

if (
initialImageOptions &&
(initialImageOptions.preset !== undefined ||
initialImageOptions.index !== undefined)
) {
const { index, preset } = initialImageOptions;

const { numberOfSlices } = csUtils.getImageSliceDataForVolumeViewport(
viewport
);

const imageIndex = this._getInitialImageIndex(
numberOfSlices,
index,
preset
);

csToolsUtils.jumpToSlice(viewport.element, {
imageIndex,
});
}
public async setVolumesForViewport(viewport, volumeInputArray) {
await viewport.setVolumes(volumeInputArray);

viewport.render();
});
const viewportInfo = this.getViewportInfo(viewport.id);
const initialImageOptions = viewportInfo.getInitialImageOptions();

if (
initialImageOptions &&
(initialImageOptions.preset !== undefined ||
initialImageOptions.index !== undefined)
) {
const { index, preset } = initialImageOptions;

const { numberOfSlices } =
csUtils.getImageSliceDataForVolumeViewport(viewport);

const imageIndex = this._getInitialImageIndex(
numberOfSlices,
index,
preset
);

csToolsUtils.jumpToSlice(viewport.element, {
imageIndex,
});
}

viewport.render();
}

public updateViewport(viewportIndex, viewportData) {
// Todo: keepCamera is an interim solution until we have a better solution for
// keeping the camera position when the viewport data is changed
public updateViewport(viewportIndex, viewportData, keepCamera = false) {
const viewportInfo = this.getViewportInfoByIndex(viewportIndex);

const viewportId = viewportInfo.getViewportId();
const viewport = this.getCornerstoneViewport(viewportId);
const viewportCamera = viewport.getCamera();

if (viewport instanceof VolumeViewport) {
this._setVolumeViewport(viewport, viewportData, viewportInfo);
this._setVolumeViewport(viewport, viewportData, viewportInfo).then(() => {
if (keepCamera) {
viewport.setCamera(viewportCamera);
viewport.render();
}
});

return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export type ViewportOptions = {
initialView?: string;
syncGroups?: SyncGroup[];
initialImageOptions?: InitialImageOptions;
customViewportOptions?: Record<string, unknown>;
customViewportProps?: Record<string, unknown>;
};

export type PublicViewportOptions = {
Expand All @@ -31,7 +31,7 @@ export type PublicViewportOptions = {
initialView?: string;
syncGroups?: SyncGroup[];
initialImageOptions?: InitialImageOptions;
customViewportOptions?: Record<string, unknown>;
customViewportProps?: Record<string, unknown>;
};

export type PublicDisplaySetOptions = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ function getDisplayText(mappedAnnotations, displaySet) {

// Area is the same for all series
const { length, width, SeriesNumber, SOPInstanceUID } = mappedAnnotations[0];
const roundedLength = utils.roundNumber(length, 1);
const roundedWidth = utils.roundNumber(width, 1);
const roundedLength = utils.roundNumber(length, 2);
const roundedWidth = utils.roundNumber(width, 2);

const instance = displaySet.images.find(
image => image.SOPInstanceUID === SOPInstanceUID
Expand Down
1 change: 0 additions & 1 deletion extensions/default/src/getPTImageIdInstanceMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ export default function getPTImageIdInstanceMetadata(
dicomMetaData.CorrectedImage === undefined ||
dicomMetaData.Units === undefined ||
!dicomMetaData.RadiopharmaceuticalInformationSequence ||
!dicomMetaData.RadiopharmaceuticalInformationSequence.length ||
dicomMetaData.RadiopharmaceuticalInformationSequence[0]
.RadionuclideHalfLife === undefined ||
dicomMetaData.RadiopharmaceuticalInformationSequence[0]
Expand Down
10 changes: 5 additions & 5 deletions extensions/default/src/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,22 @@ const handlePETImageMetadata = ({ SeriesInstanceUID, StudyInstanceUID }) => {
return;
}
const imageIds = instances.map(instance => instance.imageId);
const InstanceMetadataArray = [];
const instanceMetadataArray = [];
imageIds.forEach(imageId => {
const instanceMetadata = getPTImageIdInstanceMetadata(imageId);
if (instanceMetadata) {
InstanceMetadataArray.push(instanceMetadata);
instanceMetadataArray.push(instanceMetadata);
}
});

if (!InstanceMetadataArray.length) {
if (!instanceMetadataArray.length) {
return;
}

// try except block to prevent errors when the metadata is not correct
let suvScalingFactors;
try {
suvScalingFactors = calculateSUVScalingFactors(InstanceMetadataArray);
suvScalingFactors = calculateSUVScalingFactors(instanceMetadataArray);
} catch (error) {
console.log(error);
}
Expand All @@ -60,7 +60,7 @@ const handlePETImageMetadata = ({ SeriesInstanceUID, StudyInstanceUID }) => {
return;
}

InstanceMetadataArray.forEach((instanceMetadata, index) => {
instanceMetadataArray.forEach((instanceMetadata, index) => {
metadataProvider.addCustomMetadata(
imageIds[index],
'scalingModule',
Expand Down
4 changes: 2 additions & 2 deletions extensions/measurement-tracking/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
"peerDependencies": {
"@ohif/core": "^3.0.0",
"classnames": "^2.2.6",
"@cornerstonejs/core": "^0.13.11",
"@cornerstonejs/tools": "^0.20.15",
"@cornerstonejs/core": "^0.14.4",
"@cornerstonejs/tools": "^0.21.7",
"@ohif/extension-cornerstone-dicom-sr": "^3.0.0",
"dcmjs": "^0.24.5",
"prop-types": "^15.6.2",
Expand Down
Loading

0 comments on commit 10b4ed5

Please sign in to comment.