feat(hp): Add displayArea option for Hanging protocols and example with Mamo(#3808)
This commit is contained in:
1 parent
cb30b97610
commit
18ac08ed86
28 files changed
+771
-27
No files matched your search
@@ -20,6 +20,7 @@ const PUBLIC_URL = process.env.PUBLIC_URL || '/';
|
||||
const APP_CONFIG = process.env.APP_CONFIG || 'config/default.js';
|
||||
const PROXY_TARGET = process.env.PROXY_TARGET;
|
||||
const PROXY_DOMAIN = process.env.PROXY_DOMAIN;
|
||||
const OHIF_PORT = Number(process.env.OHIF_PORT || 3000);
|
||||
const ENTRY_TARGET = process.env.ENTRY_TARGET || `${SRC_DIR}/index.js`;
|
||||
const Dotenv = require('dotenv-webpack');
|
||||
const writePluginImportFile = require('./writePluginImportsFile.js');
|
||||
@@ -143,7 +144,7 @@ module.exports = (env, argv) => {
|
||||
// http2: true,
|
||||
// https: true,
|
||||
open: true,
|
||||
port: 3000,
|
||||
port: OHIF_PORT,
|
||||
client: {
|
||||
overlay: { errors: true, warnings: false },
|
||||
},
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
import { utilities } from '@cornerstonejs/core';
|
||||
|
||||
/**
|
||||
* Add tests to ensure image consistency and quality
|
||||
*/
|
||||
|
||||
const testPixel = (dx, dy, expectedPixel) => {
|
||||
cy.get('.cornerstone-canvas').then(v => {
|
||||
const canvas = v[0];
|
||||
cy.log(
|
||||
'testPixel canvas',
|
||||
dx,
|
||||
dy,
|
||||
expectedPixel,
|
||||
canvas.width,
|
||||
canvas.height,
|
||||
canvas.style.width,
|
||||
canvas.style.height
|
||||
);
|
||||
const ctx = canvas.getContext('2d');
|
||||
cy.window()
|
||||
.its('cornerstone')
|
||||
.then(cornerstone => {
|
||||
const { viewport } = cornerstone.getEnabledElements()[0];
|
||||
const imageData = viewport.getImageData();
|
||||
// cy.log("imageData", imageData);
|
||||
const origin = viewport.worldToCanvas(imageData.origin);
|
||||
const orX = origin[0] * devicePixelRatio;
|
||||
const orY = origin[1] * devicePixelRatio;
|
||||
const x = Math.round(orX + dx);
|
||||
const y = Math.round(orY + dy);
|
||||
cy.log('testPixel origin x,y point x,y', orX, orY, x, y);
|
||||
// cy.log('world origin', imageData.origin);
|
||||
// cy.log('focal', viewport.getCamera().focalPoint,
|
||||
// viewport.worldToCanvas(viewport.getCamera().focalPoint));
|
||||
const pixelData = ctx.getImageData(x, y, 1, 1);
|
||||
|
||||
expect(pixelData.data[0]).closeTo(expectedPixel, 1);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
describe('CS3D Image Consistency and Quality', () => {
|
||||
const setupStudySeries = (studyUID, seriesUID) => {
|
||||
cy.checkStudyRouteInViewer(
|
||||
studyUID,
|
||||
`&seriesInstanceUID=${seriesUID}&hangingProtocolId=@ohif/hpScale`
|
||||
);
|
||||
cy.initCornerstoneToolsAliases();
|
||||
cy.initCommonElementsAliases();
|
||||
};
|
||||
|
||||
it('TG18 Resolution Test Displayed 1:1', () => {
|
||||
setupStudySeries(
|
||||
'2.16.124.113543.6004.101.103.20021117.061159.1',
|
||||
'2.16.124.113543.6004.101.103.20021117.061159.1.004'
|
||||
);
|
||||
testPixel(1018, 1028, 255);
|
||||
// Horizontal and vertical delta from this should not be contaminated
|
||||
// by values from center
|
||||
testPixel(1019, 1028, 0);
|
||||
testPixel(1018, 1029, 0);
|
||||
testPixel(1017, 1028, 0);
|
||||
testPixel(1018, 1027, 0);
|
||||
});
|
||||
|
||||
// Missing test data - todo
|
||||
it.skip('8 bit image displayable', () => {
|
||||
setupStudySeries('1.3.46.670589.17.1.7.1.1.7', '1.3.46.670589.17.1.7.2.1.7');
|
||||
|
||||
// Compare with dcm2jpg generated values or by manually computing WL values
|
||||
testPixel(258, 257, 171);
|
||||
testPixel(259, 257, 166);
|
||||
});
|
||||
|
||||
it.skip('12 bit image displayable and zoom with pixel spacing', () => {
|
||||
setupStudySeries(
|
||||
'1.3.6.1.4.1.25403.345050719074.3824.20170125113417.1',
|
||||
'1.3.6.1.4.1.25403.345050719074.3824.20170125113608.5'
|
||||
);
|
||||
|
||||
// Compare with dcm2jpg generated values or by manually computing WL values
|
||||
testPixel(258, 277, 120);
|
||||
testPixel(259, 277, 122);
|
||||
});
|
||||
});
|
||||
@@ -111,6 +111,34 @@ window.config = {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
|
||||
sourceName: 'dicomweb2',
|
||||
configuration: {
|
||||
friendlyName: 'AWS S3 Static wado secondary server',
|
||||
name: 'aws',
|
||||
wadoUriRoot: 'https://d28o5kq0jsoob5.cloudfront.net/dicomweb',
|
||||
qidoRoot: 'https://d28o5kq0jsoob5.cloudfront.net/dicomweb',
|
||||
wadoRoot: 'https://d28o5kq0jsoob5.cloudfront.net/dicomweb',
|
||||
qidoSupportsIncludeField: false,
|
||||
supportsReject: false,
|
||||
imageRendering: 'wadors',
|
||||
thumbnailRendering: 'wadors',
|
||||
enableStudyLazyLoad: true,
|
||||
supportsFuzzyMatching: false,
|
||||
supportsWildcard: true,
|
||||
staticWado: true,
|
||||
singlepart: 'bulkdata,video',
|
||||
// whether the data source should use retrieveBulkData to grab metadata,
|
||||
// and in case of relative path, what would it be relative to, options
|
||||
// are in the series level or study level (some servers like series some study)
|
||||
bulkDataURI: {
|
||||
enabled: true,
|
||||
relativeResolution: 'studies',
|
||||
},
|
||||
omitQuotationForMultipartRequest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
friendlyName: 'StaticWado default data',
|
||||
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
|
||||
|
||||
@@ -24,6 +24,18 @@ export type DisplaySetAndViewportOptions = {
|
||||
displaySetOptions: DisplaySetOptions;
|
||||
};
|
||||
|
||||
export type DisplayArea = {
|
||||
type?: 'SCALE' | 'FIT';
|
||||
scale?: number;
|
||||
interpolationType?: any;
|
||||
imageArea?: [number, number]; // areaX, areaY
|
||||
imageCanvasPoint?: {
|
||||
imagePoint: [number, number]; // imageX, imageY
|
||||
canvasPoint?: [number, number]; // canvasX, canvasY
|
||||
};
|
||||
storeAsInitialCamera?: boolean;
|
||||
};
|
||||
|
||||
export type SetProtocolOptions = {
|
||||
/** Used to provide a mapping of what keys are provided for which viewport.
|
||||
* For example, a Chest XRay might use have the display set selector id of
|
||||
@@ -155,6 +167,7 @@ export type ViewportOptions = {
|
||||
id?: string;
|
||||
orientation?: CustomOption<string>;
|
||||
viewportId?: string;
|
||||
displayArea?: DisplayArea;
|
||||
initialImageOptions?: CustomOption<initialImageOptions>;
|
||||
syncGroups?: CustomOption<SyncGroup>[];
|
||||
customViewportProps?: Record<string, unknown>;
|
||||
|
||||
@@ -293,6 +293,7 @@ alternative data source (or even specify different default hotkeys).
|
||||
| `APP_CONFIG` | Which [configuration file][config-file] to copy to output as `app-config.js` | `config/default.js` |
|
||||
| `PROXY_TARGET` | When developing, proxy requests that match this pattern to `PROXY_DOMAIN` | `undefined` |
|
||||
| `PROXY_DOMAIN` | When developing, proxy requests from `PROXY_TARGET` to `PROXY_DOMAIN` | `undefined` |
|
||||
| `OHIF_PORT` | The port to run the webpack server on for PWA builds. | `3000` |
|
||||
|
||||
You can also create a new config file and specify its path relative to the build
|
||||
output's root by setting the `APP_CONFIG` environment variable. You can set the
|
||||
|
||||
@@ -281,21 +281,22 @@ A list of criteria for the protocol along with the provided points for ranking.
|
||||
},
|
||||
```
|
||||
|
||||
### `from` attribute
|
||||
The from attribute allows getting the attribute to test from some other object
|
||||
such as the prior study, the list of studies overall or another module provided
|
||||
value. Some of the possible attributes are:
|
||||
### `from` attribute (optional)
|
||||
The `from` attribute allows you to retrieve the attribute to test from another object, such as the previous study, the overall list of studies, or another provided value from a module.
|
||||
|
||||
* `prior`: To get the value from the prior study.
|
||||
* `activeStudy`: To match the active study
|
||||
* `studies`: To match the list of studies to display
|
||||
* `displaySets`: The display sets for the current study
|
||||
* `allDisplaySets`: Alll available display sets
|
||||
* `instance`: An instance from the current display set being tested
|
||||
* `options`: Gets the options object itself, eg if you want a simple top level
|
||||
value.
|
||||
The values provided by OHIF which you can use are:
|
||||
|
||||
### displaySetSelectors
|
||||
- `activeStudy`: to use the metadata of the active study to match
|
||||
- `studies`: to use the metadata of the list of studies (all studies) to match
|
||||
- `allDisplaySets`: all available display sets
|
||||
- `displaySets`: if the selector has matched a study, these are the display sets for that study
|
||||
- `prior`: the metadata of the first study in the list of studies that is not the active study
|
||||
- `options`: during matching, we also provide an options object with the following information that you can use as the `from` value:
|
||||
- `studyInstanceUIDsIndex`: the index of the study in the list of studies
|
||||
- `instance`: the metadata of the instance being matched, which is exactly the displaySet.instance metadata.
|
||||
|
||||
|
||||
### displaySetSelectors (mandatory)
|
||||
Defines the display sets that the protocol will use for arrangement.
|
||||
|
||||
```js
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
"react-window": "^1.8.9",
|
||||
"react-with-direction": "^1.3.1",
|
||||
"swiper": "^8.4.2",
|
||||
"webpack": "^5.81.0"
|
||||
"webpack": "^5.89.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.23.2",
|
||||
|
||||
Reference in new issue
Block a user