Compare commits

...
Author SHA1 Message Date
ohif-bot 57de66a65f chore(release): publish [skip ci]
- @ohif/viewer@3.8.9
2020-03-25 17:55:57 +00:00
Kedarandkedar.netelixir 99022f2bac fix: Load measurement in active viewport. (#1558)
Possible solution for request https://github.com/OHIF/Viewers/issues/1522 ?

Co-authored-by: kedar.netelixir <kedar.choudhary@netelixir.com>
2020-03-25 13:53:47 -04:00
ohif-bot 47b1e2837f chore(release): publish [skip ci]
- @ohif/extension-vtk@1.3.5
 - @ohif/core@2.6.4
 - @ohif/viewer@3.8.8
2020-03-25 17:04:29 +00:00
Kedarandkedar.netelixir d604ebaffd fix: disable autoFreeze of immer, even in dev mode (#1560)
Co-authored-by: kedar.netelixir <kedar.choudhary@netelixir.com>
2020-03-25 12:56:46 -04:00
Erik ZieglerandDanny Brown c1a0d3c662 fix: Add support for single entries in SequenceOfUltrasoundRegions. M… (#1559)
* fix: Add support for single entries in SequenceOfUltrasoundRegions. More than one region will need lower-level changes

* Update platform/core/src/utils/metadataProvider/getPixelSpacingInformation.js

Co-authored-by: Danny Brown <danny.ri.brown@gmail.com>
2020-03-25 12:55:39 -04:00
ohif-bot 16866a47a0 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.3.4
 - @ohif/core@2.6.3
 - @ohif/viewer@3.8.7
2020-03-24 17:13:15 +00:00
Erik Ziegler 77ab0ad9a1 fix: Ensure we take into account pixel spacing fields properly (#1555)
* fix: Ensure we take into account pixel spacing fields properly

* Rename to getPixelSpacingInformation
2020-03-24 18:10:58 +01:00
ohif-bot 1c306dd243 chore(release): publish [skip ci]
- @ohif/extension-vtk@1.3.3
 - @ohif/core@2.6.2
 - @ohif/viewer@3.8.6
2020-03-24 15:19:55 +00:00
Erik Ziegler 404d52fe5c fix: OverlayPlane module usage for ArrayBuffer, BulkDataURI, and InlineBinary cases, as well as PaletteColor LUTs for ArrayBuffer (i.e. local drag/drop) case (#1546) 2020-03-24 16:18:13 +01:00
15 changed files with 289 additions and 92 deletions

No files matched your search

+24
View File
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.3.5](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.3.4...@ohif/extension-vtk@1.3.5) (2020-03-25)
**Note:** Version bump only for package @ohif/extension-vtk
## [1.3.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.3.3...@ohif/extension-vtk@1.3.4) (2020-03-24)
**Note:** Version bump only for package @ohif/extension-vtk
## [1.3.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.3.2...@ohif/extension-vtk@1.3.3) (2020-03-24)
**Note:** Version bump only for package @ohif/extension-vtk
## [1.3.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.3.1...@ohif/extension-vtk@1.3.2) (2020-03-23)
**Note:** Version bump only for package @ohif/extension-vtk
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-vtk",
"version": "1.3.2",
"version": "1.3.5",
"description": "OHIF extension for VTK.js",
"author": "OHIF",
"license": "MIT",
@@ -53,7 +53,7 @@
"react-vtkjs-viewport": "^0.8.3"
},
"devDependencies": {
"@ohif/core": "^2.6.1",
"@ohif/core": "^2.6.4",
"@ohif/ui": "^1.4.1",
"cornerstone-tools": "4.12.5",
"cornerstone-wado-image-loader": "^3.0.0",
+34
View File
@@ -3,6 +3,40 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.6.4](https://github.com/OHIF/Viewers/compare/@ohif/core@2.6.3...@ohif/core@2.6.4) (2020-03-25)
### Bug Fixes
* Add support for single entries in SequenceOfUltrasoundRegions. M… ([#1559](https://github.com/OHIF/Viewers/issues/1559)) ([c1a0d3c](https://github.com/OHIF/Viewers/commit/c1a0d3c662d143b62dfbf1c01f6ce394af3756ca))
* disable autoFreeze of immer, even in dev mode ([#1560](https://github.com/OHIF/Viewers/issues/1560)) ([d604eba](https://github.com/OHIF/Viewers/commit/d604ebaffd93f688eadd0081e402f27074dd226b))
## [2.6.3](https://github.com/OHIF/Viewers/compare/@ohif/core@2.6.2...@ohif/core@2.6.3) (2020-03-24)
### Bug Fixes
* Ensure we take into account pixel spacing fields properly ([#1555](https://github.com/OHIF/Viewers/issues/1555)) ([77ab0ad](https://github.com/OHIF/Viewers/commit/77ab0ad9a14a135b5560741fc1600704df08c141))
## [2.6.2](https://github.com/OHIF/Viewers/compare/@ohif/core@2.6.1...@ohif/core@2.6.2) (2020-03-24)
### Bug Fixes
* OverlayPlane module usage for ArrayBuffer, BulkDataURI, and InlineBinary cases, as well as PaletteColor LUTs for ArrayBuffer (i.e. local drag/drop) case ([#1546](https://github.com/OHIF/Viewers/issues/1546)) ([404d52f](https://github.com/OHIF/Viewers/commit/404d52fe5c0442dd13e4d407bb0687d72fa5f32c))
## [2.6.1](https://github.com/OHIF/Viewers/compare/@ohif/core@2.6.0...@ohif/core@2.6.1) (2020-03-23)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/core",
"version": "2.6.1",
"version": "2.6.4",
"description": "Generic business logic for web-based medical imaging applications",
"author": "OHIF Core Team",
"license": "MIT",
+11 -22
View File
@@ -1,7 +1,7 @@
import * as dcmjs from 'dcmjs';
import queryString from 'query-string';
import dicomParser from 'dicom-parser';
import { getFallbackTagFromInstance } from '../utils/metadataProvider/metadataProviderFallbackTags';
import getPixelSpacingInformation from '../utils/metadataProvider/getPixelSpacingInformation';
import fetchPaletteColorLookupTableData from '../utils/metadataProvider/fetchPaletteColorLookupTableData';
import fetchOverlayData from '../utils/metadataProvider/fetchOverlayData';
@@ -58,9 +58,7 @@ class MetadataProvider {
Object.assign(instance, naturalizedDataset);
if (options.server) {
await this._checkBulkDataAndInlineBinaries(instance, options.server);
}
await this._checkBulkDataAndInlineBinaries(instance, options.server);
return instance;
}
@@ -163,18 +161,6 @@ class MetadataProvider {
return instance[naturalizedTagOrWADOImageLoaderTag];
}
if (options.fallback) {
// Perhaps the tag has fallbacks?
const fallbackTag = getFallbackTagFromInstance(
naturalizedTagOrWADOImageLoaderTag,
instance
);
if (fallbackTag) {
return fallbackTag;
}
}
// Maybe its a legacy CornerstoneWADOImageLoader tag then:
return this._getCornerstoneWADOImageLoaderTag(
naturalizedTagOrWADOImageLoaderTag,
@@ -220,10 +206,9 @@ class MetadataProvider {
const { ImageOrientationPatient } = instance;
// Fallback for DX images.
const PixelSpacing = getFallbackTagFromInstance(
'PixelSpacing',
instance
);
// TODO: We should use the rest of the results of this function
// to update the UI somehow
const { PixelSpacing } = getPixelSpacingInformation(instance);
let rowPixelSpacing;
let columnPixelSpacing;
@@ -344,7 +329,7 @@ class MetadataProvider {
break;
case WADO_IMAGE_LOADER_TAGS.OVERLAY_PLANE_MODULE:
metadata = [];
const overlays = [];
for (
let overlayGroup = 0x00;
@@ -389,9 +374,13 @@ class MetadataProvider {
roiStandardDeviation: instance[ROIStandardDeviationTag],
};
metadata.push(overlay);
overlays.push(overlay);
}
metadata = {
overlays
};
break;
case WADO_IMAGE_LOADER_TAGS.PATIENT_MODULE:
@@ -1,5 +1,5 @@
import cloneDeep from 'lodash.clonedeep';
import produce from 'immer';
import produce, { setAutoFreeze } from 'immer';
import {
CLEAR_VIEWPORT,
@@ -11,6 +11,8 @@ import {
SET_VIEWPORT_LAYOUT_AND_DATA,
} from './../constants/ActionTypes.js';
setAutoFreeze(false);
export const DEFAULT_STATE = {
numRows: 1,
numColumns: 1,
@@ -1,5 +1,7 @@
import { api } from 'dicomweb-client';
import DICOMWeb from '../../DICOMWeb';
import str2ab from '../str2ab';
import unpackOverlay from './unpackOverlay';
export default async function fetchOverlayData(instance, server) {
const OverlayDataPromises = [];
@@ -15,11 +17,18 @@ export default async function fetchOverlayData(instance, server) {
const OverlayDataTag = `${groupStr}3000`;
if (instance[OverlayDataTag] && instance[OverlayDataTag].BulkDataURI) {
if (instance[OverlayDataTag] && instance[OverlayDataTag].InlineBinary) {
const inlineBinaryData = atob(instance[OverlayDataTag].InlineBinary);
const arraybuffer = str2ab(inlineBinaryData);
instance[OverlayDataTag] = unpackOverlay(arraybuffer)
} else if (instance[OverlayDataTag] && instance[OverlayDataTag].BulkDataURI) {
OverlayDataPromises.push(
_getOverlayData(instance[OverlayDataTag], server)
);
OverlayDataTags.push(OverlayDataTag);
} else if (instance[OverlayDataTag] && instance[OverlayDataTag] instanceof ArrayBuffer) {
instance[OverlayDataTag] = unpackOverlay(instance[OverlayDataTag])
}
}
@@ -60,19 +69,7 @@ async function _getOverlayData(tag, server) {
return dicomWeb
.retrieveBulkData(options)
.then(result => result[0])
.then(_unpackOverlay);
.then(unpackOverlay);
}
function _unpackOverlay(arrayBuffer) {
const bitArray = new Uint8Array(arrayBuffer);
const byteArray = new Uint8Array(8 * bitArray.length);
for (let byteIndex = 0; byteIndex < byteArray.length; byteIndex++) {
const bitIndex = byteIndex % 8;
const bitByteIndex = Math.floor(byteIndex / 8);
byteArray[byteIndex] =
1 * ((bitArray[bitByteIndex] & (1 << bitIndex)) >> bitIndex);
}
return byteArray;
}
@@ -1,5 +1,6 @@
import { api } from 'dicomweb-client';
import DICOMWeb from '../../DICOMWeb';
import str2ab from '../str2ab';
export default async function fetchPaletteColorLookupTableData(
instance,
@@ -157,31 +158,12 @@ function _getPaletteColor(server, paletteColorLookupTableData, lutDescriptor) {
.then(arrayBufferToPaletteColorLUT);
} else if (paletteColorLookupTableData.InlineBinary) {
const inlineBinaryData = atob(paletteColorLookupTableData.InlineBinary);
const arraybuffer = _str2ab(inlineBinaryData);
const arraybuffer = str2ab(inlineBinaryData);
return new Promise(resolve => {
resolve(arrayBufferToPaletteColorLUT(arraybuffer));
});
} else {
return Promise.resolve(arrayBufferToPaletteColorLUT(paletteColorLookupTableData));
}
throw new Error(
'Palette Color LUT was not provided as InlineBinary or BulkDataURI'
);
}
/**
* Convert String to ArrayBuffer
*
* @param {String} str Input String
* @return {ArrayBuffer} Output converted ArrayBuffer
*/
function _str2ab(str) {
const strLen = str.length;
const bytes = new Uint8Array(strLen);
for (let i = 0; i < strLen; i++) {
bytes[i] = str.charCodeAt(i);
}
return bytes.buffer;
}
@@ -0,0 +1,130 @@
import log from '../../log';
export default function getPixelSpacingInformation(instance) {
// See http://gdcm.sourceforge.net/wiki/index.php/Imager_Pixel_Spacing
// TODO: Add Ultrasound region spacing
// TODO: Add manual calibration
// TODO: Use ENUMS from dcmjs
const projectionRadiographSOPClassUIDs = [
'1.2.840.10008.5.1.4.1.1.1', // CR Image Storage
'1.2.840.10008.5.1.4.1.1.1.1', // Digital X-Ray Image Storage – for Presentation
'1.2.840.10008.5.1.4.1.1.1.1.1', // Digital X-Ray Image Storage – for Processing
'1.2.840.10008.5.1.4.1.1.1.2', // Digital Mammography X-Ray Image Storage – for Presentation
'1.2.840.10008.5.1.4.1.1.1.2.1', // Digital Mammography X-Ray Image Storage – for Processing
'1.2.840.10008.5.1.4.1.1.1.3', // Digital Intra – oral X-Ray Image Storage – for Presentation
'1.2.840.10008.5.1.4.1.1.1.3.1', // Digital Intra – oral X-Ray Image Storage – for Processing
'1.2.840.10008.5.1.4.1.1.12.1', // X-Ray Angiographic Image Storage
'1.2.840.10008.5.1.4.1.1.12.1.1', // Enhanced XA Image Storage
'1.2.840.10008.5.1.4.1.1.12.2', // X-Ray Radiofluoroscopic Image Storage
'1.2.840.10008.5.1.4.1.1.12.2.1', // Enhanced XRF Image Storage
'1.2.840.10008.5.1.4.1.1.12.3', // X-Ray Angiographic Bi-plane Image Storage Retired
];
const {
PixelSpacing,
ImagerPixelSpacing,
SOPClassUID,
PixelSpacingCalibrationType,
PixelSpacingCalibrationDescription,
EstimatedRadiographicMagnificationFactor,
SequenceOfUltrasoundRegions,
} = instance;
const isProjection = projectionRadiographSOPClassUIDs.includes(SOPClassUID);
const TYPES = {
NOT_APPLICABLE: 'NOT_APPLICABLE',
UNKNOWN: 'UNKNOWN',
CALIBRATED: 'CALIBRATED',
DETECTOR: 'DETECTOR',
};
if (isProjection && !ImagerPixelSpacing) {
// If only Pixel Spacing is present, and this is a projection radiograph,
// PixelSpacing should be used, but the user should be informed that
// what it means is unknown
return {
PixelSpacing,
type: TYPES.UNKNOWN,
isProjection,
};
} else if (
PixelSpacing &&
ImagerPixelSpacing &&
PixelSpacing === ImagerPixelSpacing
) {
// If Imager Pixel Spacing and Pixel Spacing are present and they have the same values,
// then the user should be informed that the measurements are at the detector plane
return {
PixelSpacing,
type: TYPES.DETECTOR,
isProjection,
};
} else if (
PixelSpacing &&
ImagerPixelSpacing &&
PixelSpacing !== ImagerPixelSpacing
) {
// If Imager Pixel Spacing and Pixel Spacing are present and they have different values,
// then the user should be informed that these are "calibrated"
// (in some unknown manner if Pixel Spacing Calibration Type and/or
// Pixel Spacing Calibration Description are absent)
return {
PixelSpacing,
type: TYPES.CALIBRATED,
isProjection,
PixelSpacingCalibrationType,
PixelSpacingCalibrationDescription,
};
} else if (!PixelSpacing && ImagerPixelSpacing) {
let CorrectedImagerPixelSpacing = ImagerPixelSpacing;
if (EstimatedRadiographicMagnificationFactor) {
// Note that in IHE Mammo profile compliant displays, the value of Imager Pixel Spacing is required to be corrected by
// Estimated Radiographic Magnification Factor and the user informed of that.
// TODO: should this correction be done before all of this logic?
CorrectedImagerPixelSpacing = ImagerPixelSpacing.map(
pixelSpacing => pixelSpacing / EstimatedRadiographicMagnificationFactor
);
} else {
log.info(
'EstimatedRadiographicMagnificationFactor was not present. Unable to correct ImagerPixelSpacing.'
);
}
return {
PixelSpacing: CorrectedImagerPixelSpacing,
isProjection,
};
} else if (
SequenceOfUltrasoundRegions &&
typeof SequenceOfUltrasoundRegions === 'object'
) {
const { PhysicalDeltaX, PhysicalDeltaY } = SequenceOfUltrasoundRegions;
const USPixelSpacing = [PhysicalDeltaX * 10, PhysicalDeltaY * 10];
return {
PixelSpacing: USPixelSpacing,
};
} else if (
SequenceOfUltrasoundRegions &&
Array.isArray(SequenceOfUltrasoundRegions) &&
SequenceOfUltrasoundRegions.length > 1
) {
log.warn(
'Sequence of Ultrasound Regions > one entry. This is not yet implemented, all measurements will be shown in pixels.'
);
} else if (isProjection === false && !ImagerPixelSpacing) {
// If only Pixel Spacing is present, and this is not a projection radiograph,
// we can stop here
return {
PixelSpacing,
type: TYPES.NOT_APPLICABLE,
isProjection,
};
}
log.info(
'Unknown combination of PixelSpacing and ImagerPixelSpacing identified. Unable to determine spacing.'
);
}
@@ -1,27 +0,0 @@
import log from '../../log';
function getFallbackTagFromInstance(tag, instance) {
if (instance[tag]) {
return instance[tag];
}
const fallbackTags = fallbackTagsMap[tag];
if (fallbackTags) {
for (let i = 0; i < fallbackTags.length; i++) {
const fallbackTag = fallbackTags[i];
if (instance[fallbackTag]) {
log.info(`metadata provider fallback tag ${tag} to ${fallbackTag}`);
return instance[fallbackTag];
}
}
}
}
const fallbackTagsMap = {
PixelSpacing: ['ImagerPixelSpacing'],
};
export { fallbackTagsMap, getFallbackTagFromInstance };
@@ -0,0 +1,13 @@
export default function unpackOverlay(arrayBuffer) {
const bitArray = new Uint8Array(arrayBuffer);
const byteArray = new Uint8Array(8 * bitArray.length);
for (let byteIndex = 0; byteIndex < byteArray.length; byteIndex++) {
const bitIndex = byteIndex % 8;
const bitByteIndex = Math.floor(byteIndex / 8);
byteArray[byteIndex] =
1 * ((bitArray[bitByteIndex] & (1 << bitIndex)) >> bitIndex);
}
return byteArray;
}
+16
View File
@@ -0,0 +1,16 @@
/**
* Convert String to ArrayBuffer
*
* @param {String} str Input String
* @return {ArrayBuffer} Output converted ArrayBuffer
*/
export default function str2ab(str) {
const strLen = str.length;
const bytes = new Uint8Array(strLen);
for (let i = 0; i < strLen; i++) {
bytes[i] = str.charCodeAt(i);
}
return bytes.buffer;
}
+35
View File
@@ -3,6 +3,41 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.8.9](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.8.8...@ohif/viewer@3.8.9) (2020-03-25)
### Bug Fixes
* Load measurement in active viewport. ([#1558](https://github.com/OHIF/Viewers/issues/1558)) ([99022f2](https://github.com/OHIF/Viewers/commit/99022f2bac752f3cd1cedb61e222b8d411e158c8))
## [3.8.8](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.8.7...@ohif/viewer@3.8.8) (2020-03-25)
**Note:** Version bump only for package @ohif/viewer
## [3.8.7](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.8.6...@ohif/viewer@3.8.7) (2020-03-24)
**Note:** Version bump only for package @ohif/viewer
## [3.8.6](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.8.5...@ohif/viewer@3.8.6) (2020-03-24)
**Note:** Version bump only for package @ohif/viewer
## [3.8.5](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.8.4...@ohif/viewer@3.8.5) (2020-03-23)
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/viewer",
"version": "3.8.5",
"version": "3.8.9",
"description": "OHIF Viewer",
"author": "OHIF Contributors",
"license": "MIT",
@@ -48,14 +48,14 @@
},
"dependencies": {
"@babel/runtime": "^7.5.5",
"@ohif/core": "^2.6.1",
"@ohif/core": "^2.6.4",
"@ohif/extension-cornerstone": "^2.5.0",
"@ohif/extension-dicom-html": "^1.1.1",
"@ohif/extension-dicom-microscopy": "^0.50.7",
"@ohif/extension-dicom-pdf": "^1.0.2",
"@ohif/extension-dicom-segmentation": "^0.1.0",
"@ohif/extension-lesion-tracker": "^0.2.0",
"@ohif/extension-vtk": "^1.3.2",
"@ohif/extension-vtk": "^1.3.5",
"@ohif/i18n": "^0.52.7",
"@ohif/ui": "^1.4.1",
"@tanem/react-nprogress": "^1.1.25",
@@ -103,6 +103,8 @@ export default function jumpToRowItem(
displaySet.frameIndex = data.frameIndex;
}
viewportIndex =
(viewportIndex + viewportsState.activeViewportIndex) % numViewports;
viewportSpecificData.push({
viewportIndex,
displaySet,