diff --git a/.circleci/config.yml b/.circleci/config.yml
index bf44ab79e..c8c7afabe 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -6,7 +6,7 @@ orbs:
defaults: &defaults
docker:
- - image: cimg/node:18.18
+ - image: cimg/node:20.18.1
environment:
TERM: xterm
QUICK_BUILD: true
diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml
index 83577dd7c..36a22e979 100644
--- a/.github/ISSUE_TEMPLATE/bug-report.yml
+++ b/.github/ISSUE_TEMPLATE/bug-report.yml
@@ -64,7 +64,7 @@ body:
attributes:
label: 'Node version'
description: 'Your Node.js version.'
- placeholder: 'e.g., 18.16.1'
+ placeholder: 'e.g., 20.18.1'
validations:
required: true
- type: input
diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml
index 259101988..513d5c93a 100644
--- a/.github/workflows/playwright.yml
+++ b/.github/workflows/playwright.yml
@@ -22,7 +22,7 @@ jobs:
- uses: oven-sh/setup-bun@v2
- uses: actions/setup-node@v4
with:
- node-version: 18
+ node-version: 20
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Set up Git safe directory
@@ -53,7 +53,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
- node-version: 18
+ node-version: 20
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Set up Git safe directory
diff --git a/.node-version b/.node-version
index 3876fd498..f3f52b42d 100644
--- a/.node-version
+++ b/.node-version
@@ -1 +1 @@
-18.16.1
+20.9.0
diff --git a/Dockerfile b/Dockerfile
index e6310c3ba..141b139a4 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -21,7 +21,7 @@
# Stage 1: Build the application
# docker build -t ohif/viewer:latest .
-FROM node:18.16.1-slim as json-copier
+FROM node:20.18.1-slim as json-copier
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
@@ -37,7 +37,7 @@ COPY platform /usr/src/app/platform
#RUN find platform \! -name "package.json" -mindepth 2 -maxdepth 2 -print | xargs rm -rf
# Copy Files
-FROM node:18.16.1-slim as builder
+FROM node:20.18.1-slim as builder
RUN apt-get update && apt-get install -y build-essential python3
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
diff --git a/bun.lockb b/bun.lockb
index 14533e521..ed61f2956 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/extensions/cornerstone-dicom-pmap/package.json b/extensions/cornerstone-dicom-pmap/package.json
index fd95a1ff1..080e3dd85 100644
--- a/extensions/cornerstone-dicom-pmap/package.json
+++ b/extensions/cornerstone-dicom-pmap/package.json
@@ -46,8 +46,8 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
- "@cornerstonejs/adapters": "^2.7.3",
- "@cornerstonejs/core": "^2.7.3",
+ "@cornerstonejs/adapters": "^2.11.2",
+ "@cornerstonejs/core": "^2.11.2",
"@kitware/vtk.js": "32.1.1",
"react-color": "^2.19.3"
}
diff --git a/extensions/cornerstone-dicom-seg/package.json b/extensions/cornerstone-dicom-seg/package.json
index 33b726a5d..704cd5ea8 100644
--- a/extensions/cornerstone-dicom-seg/package.json
+++ b/extensions/cornerstone-dicom-seg/package.json
@@ -46,8 +46,8 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
- "@cornerstonejs/adapters": "^2.7.3",
- "@cornerstonejs/core": "^2.7.3",
+ "@cornerstonejs/adapters": "^2.11.2",
+ "@cornerstonejs/core": "^2.11.2",
"@kitware/vtk.js": "32.1.1",
"react-color": "^2.19.3"
}
diff --git a/extensions/cornerstone-dicom-sr/package.json b/extensions/cornerstone-dicom-sr/package.json
index 28840d077..5259535cd 100644
--- a/extensions/cornerstone-dicom-sr/package.json
+++ b/extensions/cornerstone-dicom-sr/package.json
@@ -46,9 +46,9 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
- "@cornerstonejs/adapters": "^2.7.3",
- "@cornerstonejs/core": "^2.7.3",
- "@cornerstonejs/tools": "^2.7.3",
+ "@cornerstonejs/adapters": "^2.11.2",
+ "@cornerstonejs/core": "^2.11.2",
+ "@cornerstonejs/tools": "^2.11.2",
"classnames": "^2.3.2"
}
}
diff --git a/extensions/cornerstone-dynamic-volume/package.json b/extensions/cornerstone-dynamic-volume/package.json
index 5f673577a..37995d236 100644
--- a/extensions/cornerstone-dynamic-volume/package.json
+++ b/extensions/cornerstone-dynamic-volume/package.json
@@ -42,8 +42,8 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
- "@cornerstonejs/core": "^2.7.3",
- "@cornerstonejs/tools": "^2.7.3",
+ "@cornerstonejs/core": "^2.11.2",
+ "@cornerstonejs/tools": "^2.11.2",
"classnames": "^2.3.2"
}
}
diff --git a/extensions/cornerstone/package.json b/extensions/cornerstone/package.json
index 0337fa230..703fe5646 100644
--- a/extensions/cornerstone/package.json
+++ b/extensions/cornerstone/package.json
@@ -38,7 +38,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5",
- "@cornerstonejs/dicom-image-loader": "^2.7.3",
+ "@cornerstonejs/dicom-image-loader": "^2.11.2",
"@icr/polyseg-wasm": "^0.4.0",
"@ohif/core": "3.10.0-beta.20",
"@ohif/ui": "3.10.0-beta.20",
@@ -55,9 +55,9 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
- "@cornerstonejs/adapters": "^2.7.3",
- "@cornerstonejs/core": "^2.7.3",
- "@cornerstonejs/tools": "^2.7.3",
+ "@cornerstonejs/adapters": "^2.11.2",
+ "@cornerstonejs/core": "^2.11.2",
+ "@cornerstonejs/tools": "^2.11.2",
"@icr/polyseg-wasm": "^0.4.0",
"@kitware/vtk.js": "32.1.1",
"html2canvas": "^1.4.1",
diff --git a/extensions/cornerstone/src/panels/PanelSegmentation.tsx b/extensions/cornerstone/src/panels/PanelSegmentation.tsx
index 8298d4e44..a402531b8 100644
--- a/extensions/cornerstone/src/panels/PanelSegmentation.tsx
+++ b/extensions/cornerstone/src/panels/PanelSegmentation.tsx
@@ -171,51 +171,61 @@ export default function PanelSegmentation({
onSegmentationDownload,
onSegmentationDownloadRTSS,
t,
- }) => (
-
- onSegmentationAdd(activeSegmentation.id)}>
-
- {t('Create New Segmentation')}
-
-
- {t('Manage Current Segmentation')}
- onSegmentationRemoveFromViewport(activeSegmentation.id)}>
-
- {t('Remove from Viewport')}
-
- onSegmentationEdit(activeSegmentation.id)}>
-
- {t('Rename')}
-
-
- {
+ return (
+
+ onSegmentationAdd(activeSegmentation.segmentationId)}>
+
+ {t('Create New Segmentation')}
+
+
+ {t('Manage Current Segmentation')}
+ onSegmentationRemoveFromViewport(activeSegmentation.segmentationId)}
>
-
- {t('Export & Download')}
-
-
-
- storeSegmentation(activeSegmentation.id)}>
- {t('Export DICOM SEG')}
-
- onSegmentationDownload(activeSegmentation.id)}>
- {t('Download DICOM SEG')}
-
- onSegmentationDownloadRTSS(activeSegmentation.id)}>
- {t('Download DICOM RTSTRUCT')}
-
-
-
-
-
- onSegmentationDelete(activeSegmentation.id)}>
-
- {t('Delete')}
-
-
- )
+
+ {t('Remove from Viewport')}
+
+ onSegmentationEdit(activeSegmentation.segmentationId)}>
+
+ {t('Rename')}
+
+
+
+
+ {t('Export & Download')}
+
+
+
+ storeSegmentation(activeSegmentation.segmentationId)}
+ >
+ {t('Export DICOM SEG')}
+
+ onSegmentationDownload(activeSegmentation.segmentationId)}
+ >
+ {t('Download DICOM SEG')}
+
+ {/* onSegmentationDownloadRTSS(activeSegmentation.segmentationId)}
+ >
+ {t('Download DICOM RTSTRUCT')}
+ */}
+
+
+
+
+ onSegmentationDelete(activeSegmentation.segmentationId)}>
+
+ {t('Delete')}
+
+
+ );
+ }
);
const exportOptions = segmentationsWithRepresentations.map(({ segmentation }) => {
diff --git a/extensions/measurement-tracking/package.json b/extensions/measurement-tracking/package.json
index 7ed83f065..7bbb0eff5 100644
--- a/extensions/measurement-tracking/package.json
+++ b/extensions/measurement-tracking/package.json
@@ -32,8 +32,8 @@
"start": "yarn run dev"
},
"peerDependencies": {
- "@cornerstonejs/core": "^2.7.3",
- "@cornerstonejs/tools": "^2.7.3",
+ "@cornerstonejs/core": "^2.11.2",
+ "@cornerstonejs/tools": "^2.11.2",
"@ohif/core": "3.10.0-beta.20",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.20",
"@ohif/extension-default": "3.10.0-beta.20",
diff --git a/platform/app/.recipes/Nginx-Dcm4chee-Keycloak/dockerfile b/platform/app/.recipes/Nginx-Dcm4chee-Keycloak/dockerfile
index bf610e8bd..4182de82b 100644
--- a/platform/app/.recipes/Nginx-Dcm4chee-Keycloak/dockerfile
+++ b/platform/app/.recipes/Nginx-Dcm4chee-Keycloak/dockerfile
@@ -1,5 +1,5 @@
# Stage 1: Build the application
-FROM node:18.16.1-slim as builder
+FROM node:20.18.1-slim as builder
# Setup the working directory
RUN mkdir /usr/src/app
diff --git a/platform/app/.recipes/Nginx-Dcm4chee/dockerfile b/platform/app/.recipes/Nginx-Dcm4chee/dockerfile
index d28e96056..bbc6f89eb 100644
--- a/platform/app/.recipes/Nginx-Dcm4chee/dockerfile
+++ b/platform/app/.recipes/Nginx-Dcm4chee/dockerfile
@@ -1,5 +1,5 @@
# Stage 1: Build the application
-FROM node:18.16.1-slim as builder
+FROM node:20.18.1-slim as builder
# Setup the working directory
RUN mkdir /usr/src/app
diff --git a/platform/app/.recipes/Nginx-Orthanc-Keycloak/dockerfile b/platform/app/.recipes/Nginx-Orthanc-Keycloak/dockerfile
index eba4237b4..7e8613529 100644
--- a/platform/app/.recipes/Nginx-Orthanc-Keycloak/dockerfile
+++ b/platform/app/.recipes/Nginx-Orthanc-Keycloak/dockerfile
@@ -1,5 +1,5 @@
# Stage 1: Build the application
-FROM node:18.16.1-slim as builder
+FROM node:20.18.1-slim as builder
# Setup the working directory
RUN mkdir /usr/src/app
diff --git a/platform/app/.recipes/Nginx-Orthanc/dockerfile b/platform/app/.recipes/Nginx-Orthanc/dockerfile
index ac7433ac6..846c74c31 100644
--- a/platform/app/.recipes/Nginx-Orthanc/dockerfile
+++ b/platform/app/.recipes/Nginx-Orthanc/dockerfile
@@ -1,5 +1,5 @@
# Stage 1: Build the application
-FROM node:18.16.1-slim as builder
+FROM node:20.18.1-slim as builder
# Setup the working directory
RUN mkdir /usr/src/app
diff --git a/platform/app/netlify.toml b/platform/app/netlify.toml
index 9e4a6e5ee..b2bd54893 100644
--- a/platform/app/netlify.toml
+++ b/platform/app/netlify.toml
@@ -19,7 +19,7 @@
[build.environment]
# If 'production', `yarn install` does not install devDependencies
NODE_ENV = "development"
- NODE_VERSION = "18.16.1"
+ NODE_VERSION = "20.18.1"
YARN_VERSION = "1.22.5"
RUBY_VERSION = "2.6.2"
YARN_FLAGS = "--no-ignore-optional --pure-lockfile"
diff --git a/platform/app/package.json b/platform/app/package.json
index 1c1daf590..e96413d41 100644
--- a/platform/app/package.json
+++ b/platform/app/package.json
@@ -53,7 +53,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5",
- "@cornerstonejs/dicom-image-loader": "^2.7.3",
+ "@cornerstonejs/dicom-image-loader": "^2.11.2",
"@emotion/serialize": "^1.1.3",
"@ohif/core": "3.10.0-beta.20",
"@ohif/extension-cornerstone": "3.10.0-beta.20",
diff --git a/platform/app/public/config/local_static.js b/platform/app/public/config/local_static.js
index 23e7a61ae..193ecb40c 100644
--- a/platform/app/public/config/local_static.js
+++ b/platform/app/public/config/local_static.js
@@ -12,41 +12,16 @@ window.config = {
showLoadingIndicator: true,
strictZSpacingForVolumeViewport: true,
// filterQueryParam: false,
- defaultDataSourceName: 'dicomweb',
+ defaultDataSourceName: 'local',
dataSources: [
- {
- namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
- sourceName: 'e2e',
- configuration: {
- friendlyName: 'StaticWado test data',
- // The most important field to set for static WADO
- staticWado: true,
- name: 'StaticWADO',
- wadoUriRoot: '/viewer-testdata',
- qidoRoot: '/viewer-testdata',
- wadoRoot: '/viewer-testdata',
- qidoSupportsIncludeField: false,
- imageRendering: 'wadors',
- thumbnailRendering: 'wadors',
- enableStudyLazyLoad: true,
- supportsFuzzyMatching: false,
- supportsWildcard: true,
- singlepart: 'video,thumbnail,pdf',
- omitQuotationForMultipartRequest: true,
- bulkDataURI: {
- enabled: true,
- relativeResolution: 'studies',
- },
- },
- },
{
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'local',
configuration: {
friendlyName: 'Static WADO Local Data',
name: 'DCM4CHEE',
- qidoRoot: 'http://localhost:5000/dicomweb',
- wadoRoot: 'http://localhost:5000/dicomweb',
+ qidoRoot: 'http://localhost:3001/dicomweb',
+ wadoRoot: 'http://localhost:3001/dicomweb',
qidoSupportsIncludeField: false,
supportsReject: true,
supportsStow: true,
diff --git a/platform/core/package.json b/platform/core/package.json
index 60d8f2574..f915c0a19 100644
--- a/platform/core/package.json
+++ b/platform/core/package.json
@@ -37,7 +37,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5",
- "@cornerstonejs/dicom-image-loader": "^2.7.3",
+ "@cornerstonejs/dicom-image-loader": "^2.11.2",
"@ohif/ui": "3.10.0-beta.20",
"cornerstone-math": "0.1.9",
"dicom-parser": "^1.8.21"
diff --git a/platform/docs/docs/assets/img/static-dicom-web.png b/platform/docs/docs/assets/img/static-dicom-web.png
new file mode 100644
index 000000000..fab41fc84
Binary files /dev/null and b/platform/docs/docs/assets/img/static-dicom-web.png differ
diff --git a/platform/docs/docs/configuration/dataSources/static-files.md b/platform/docs/docs/configuration/dataSources/static-files.md
index 2741e0495..ec460db2b 100644
--- a/platform/docs/docs/configuration/dataSources/static-files.md
+++ b/platform/docs/docs/configuration/dataSources/static-files.md
@@ -3,45 +3,98 @@ sidebar_position: 5
sidebar_label: Static Files
---
-# Static Files
-There is a binary DICOM to static file generator, which provides easily served
-binary files. The files are all compressed in order to reduce space
-significantly, and are pre-computed for the files required for OHIF, so that the
-performance of serving the files is just the read from disk/write to http stream
-time, without any extra processing time.
+# Static DICOMweb Files for Enhanced Performance
-The project for the static wado files is located here: [static-wado]:
-https://github.com/OHIF/static-wado
+This section describes how to generate and serve static DICOMweb files, significantly improving the performance of your OHIF Viewer setup. These files are pre-processed and compressed, minimizing storage space and reducing serving time to the bare minimum (disk read and HTTP stream write).
-It can be compiled with Java and Gradle, and then run against a set of dicom, in
-the example located in /dicom/study1 outputting to /dicomweb, and then a server
-run against that data, like this:
+## Static-DICOMWeb Project
-```bash
-git clone https://github.com/OHIF/static-wado
-cd static-wado
-./gradlew installDist
-StaticWado/build/install/StaticWado/bin/StaticWado -d /dicomweb /dicom/study1
-cd /dicomweb
-npx http-server -p 5000 --cors -g
+The core tool for this process is the `static-wado` project, available on GitHub:
-# you can use npx serve ./dist -l 8080 -c ../public/serve.json as an alternative to http-server
-```
+[static-wado]: https://github.com/RadicalImaging/Static-DICOMWeb
-There is then a dev environment in the platform/app directory which can be
-run against those files, like this:
+This project contains two main components:
-```
-cd platform/app
-yarn dev:static
-```
+* **`static-wado-creator`:** Converts raw DICOM files into a DICOMweb-compliant directory structure, optimizing them for efficient serving.
+* **`static-wado-webserver`:** A simple web server specifically designed to serve the generated static DICOMweb files.
-Additional studies can be added to the dicomweb by re-running the StaticWado
-command. It will create a single studies.gz index file (JSON DICOM file,
-compressed) containing an index of all studies created. There is then a small
-extension to OHIF which performs client side indexing.
+## Prerequisites
-The StaticWado command also knows how to deploy a client and dicomweb directory
-to Amazon s3, which can then server files up directly. There is another build
-setup build:aws in the viewer package.json to create such a deployment.
+- Node.js and npm (or yarn) installed on your system.
+
+## Installation
+
+1. **Clone the Repository:**
+
+ ```bash
+ git clone https://github.com/RadicalImaging/Static-DICOMWeb
+ cd Static-DICOMWeb
+ ```
+
+2. **Install Dependencies:**
+
+ ```bash
+ yarn install
+ ```
+
+## Generating Static DICOMweb Files
+
+1. **Prepare your DICOM data:** Organize your DICOM files into a directory. For example `/Users/alireza/dicom/test-static-script/ACRIN-CT`.
+
+2. **Convert to DICOMweb Structure:**
+ Use the `mkdicomweb.js` script from the `static-wado-creator` package to create the DICOMweb directory:
+
+ ```bash
+ node packages/static-wado-creator/bin/mkdicomweb.js '/Users/alireza/dicom/test-static-script/ACRIN-CT' -o '/Users/alireza/dicom/test-static-script/output'
+ ```
+
+ * **Replace:**
+ * `/Users/alireza/dicom/test-static-script/ACRIN-CT` with the path to your directory of DICOM files.
+ * `/Users/alireza/dicom/test-static-script/output` with your desired output directory for the DICOMweb structure.
+
+ This command will generate a directory structure similar to this in your output location:
+
+ 
+
+## Serving Static Files with the Web Server
+
+1. **Start the Server:**
+
+ Run the `dicomwebserver.mjs` script from the `static-wado-webserver` package, specifying the port and the DICOMweb directory:
+
+ ```bash
+ node packages/static-wado-webserver/bin/dicomwebserver.mjs -p 3001 -o /Users/alireza/dicom/test-static-script/output
+ ```
+
+ * **`-p 3001`:** Sets the server to listen on port 3001. You can change this if needed.
+ * **`-o /Users/alireza/dicom/test-static-script/output`:** Specifies the path to your generated DICOMweb directory.
+
+ :::info
+ The `-p` (port) and `-o` (output directory) flags are used to configure the server.
+ :::
+
+## Running OHIF Viewer with Static Data
+
+1. **Use the `local_static.js` Configuration:**
+
+ Start the OHIF Viewer in development mode using the provided `local_static.js` configuration file:
+
+ ```bash
+ yarn dev:static
+ ```
+
+2. **Configuration Details:**
+
+ The `local_static.js` configuration file is pre-configured to point to:
+
+ ```js
+ qidoRoot: 'http://localhost:3001/dicomweb',
+ wadoRoot: 'http://localhost:3001/dicomweb',
+ ```
+
+ This matches the default port (3001) used by the `static-wado-webserver`.
+
+ :::info
+ If you change the port or output directory when running the `static-wado-webserver`, you **must** also update the `qidoRoot` and `wadoRoot` values in your `local_static.js` configuration file accordingly to ensure the OHIF Viewer can access the data.
+ :::
diff --git a/platform/docs/netlify.toml b/platform/docs/netlify.toml
index ff82abc66..7354856c5 100644
--- a/platform/docs/netlify.toml
+++ b/platform/docs/netlify.toml
@@ -16,7 +16,7 @@
[build.environment]
# If 'production', `yarn install` does not install devDependencies
NODE_ENV = "development"
- NODE_VERSION = "18.16.1"
+ NODE_VERSION = "20.18.1"
YARN_VERSION = "1.22.5"
RUBY_VERSION = "2.6.2"
YARN_FLAGS = "--no-ignore-optional --pure-lockfile"