feat: Add CS3D WSI and Video Viewports and add annotation navigation for MPR (#4182)
This commit is contained in:
1 parent
b12e0211d4
commit
7599ec9421
65 files changed
+781
-513
No files matched your search
@@ -0,0 +1,78 @@
|
||||
import { fixBulkDataURI } from './fixBulkDataURI';
|
||||
|
||||
function isPrimitive(v: any) {
|
||||
return !(typeof v == 'object' || Array.isArray(v));
|
||||
}
|
||||
|
||||
const vrNumerics = new Set([
|
||||
'DS',
|
||||
'FL',
|
||||
'FD',
|
||||
'IS',
|
||||
'OD',
|
||||
'OF',
|
||||
'OL',
|
||||
'OV',
|
||||
'SL',
|
||||
'SS',
|
||||
'SV',
|
||||
'UL',
|
||||
'US',
|
||||
'UV',
|
||||
]);
|
||||
|
||||
/**
|
||||
* Specialized for DICOM JSON format dataset cleaning.
|
||||
* @param obj
|
||||
* @returns
|
||||
*/
|
||||
export function cleanDenaturalizedDataset(
|
||||
obj: any,
|
||||
options?: {
|
||||
StudyInstanceUID: string;
|
||||
SeriesInstanceUID: string;
|
||||
dataSourceConfig: unknown;
|
||||
}
|
||||
): any {
|
||||
if (Array.isArray(obj)) {
|
||||
const newAry = obj.map(o => (isPrimitive(o) ? o : cleanDenaturalizedDataset(o, options)));
|
||||
return newAry;
|
||||
}
|
||||
if (isPrimitive(obj)) {
|
||||
return obj;
|
||||
}
|
||||
Object.keys(obj).forEach(key => {
|
||||
if (obj[key].Value === null && obj[key].vr) {
|
||||
delete obj[key].Value;
|
||||
} else if (Array.isArray(obj[key].Value) && obj[key].vr) {
|
||||
if (obj[key].Value.length === 1 && obj[key].Value[0].BulkDataURI) {
|
||||
if (options?.dataSourceConfig) {
|
||||
// Not needed unless data source is directly used for loading data.
|
||||
fixBulkDataURI(obj[key].Value[0], options, options.dataSourceConfig);
|
||||
}
|
||||
|
||||
obj[key].BulkDataURI = obj[key].Value[0].BulkDataURI;
|
||||
|
||||
// prevent mixed-content blockage
|
||||
if (window.location.protocol === 'https:' && obj[key].BulkDataURI.startsWith('http:')) {
|
||||
obj[key].BulkDataURI = obj[key].BulkDataURI.replace('http:', 'https:');
|
||||
}
|
||||
delete obj[key].Value;
|
||||
} else if (vrNumerics.has(obj[key].vr)) {
|
||||
obj[key].Value = obj[key].Value.map(v => +v);
|
||||
} else {
|
||||
obj[key].Value = obj[key].Value.map(entry => cleanDenaturalizedDataset(entry, options));
|
||||
}
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is required to make the denaturalized data transferrable when it has
|
||||
* added proxy values.
|
||||
*/
|
||||
export function transferDenaturalizedDataset(dataset) {
|
||||
const noNull = cleanDenaturalizedDataset(dataset);
|
||||
return JSON.parse(JSON.stringify(noNull));
|
||||
}
|
||||
@@ -23,6 +23,8 @@ function fixBulkDataURI(value, instance, dicomWebConfig) {
|
||||
let { BulkDataURI } = value;
|
||||
const { bulkDataURI: uriConfig = {} } = dicomWebConfig;
|
||||
|
||||
BulkDataURI = uriConfig.transform?.(BulkDataURI) || BulkDataURI;
|
||||
|
||||
// Handle incorrectly prefixed origins
|
||||
const { startsWith, prefixWith = '' } = uriConfig;
|
||||
if (startsWith && BulkDataURI.startsWith(startsWith)) {
|
||||
@@ -36,7 +38,7 @@ function fixBulkDataURI(value, instance, dicomWebConfig) {
|
||||
if (
|
||||
BulkDataURI.startsWith('series/') ||
|
||||
BulkDataURI.startsWith('bulkdata/') ||
|
||||
(uriConfig.relativeResolution === 'studies' && isInstanceStart)
|
||||
(uriConfig.relativeResolution === 'studies' && !isInstanceStart)
|
||||
) {
|
||||
value.BulkDataURI = `${dicomWebConfig.wadoRoot}/studies/${StudyInstanceUID}/${BulkDataURI}`;
|
||||
} else if (
|
||||
@@ -49,7 +51,6 @@ function fixBulkDataURI(value, instance, dicomWebConfig) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// in case it is relative path but starts at the server (e.g., /bulk/1e, note the missing http
|
||||
// in the beginning and the first character is /) There are two scenarios, whether the wado root
|
||||
// is absolute or relative. In case of absolute, we need to prepend the wado root to the bulkdata
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Fix multi-valued keys so that those which are strings split by
|
||||
* a backslash are returned as arrays.
|
||||
*/
|
||||
export function fixMultiValueKeys(naturalData, keys = ['ImageType']) {
|
||||
for (const key of keys) {
|
||||
if (typeof naturalData[key] === 'string') {
|
||||
naturalData[key] = naturalData[key].split('\\');
|
||||
}
|
||||
}
|
||||
return naturalData;
|
||||
}
|
||||
@@ -1,3 +1,9 @@
|
||||
import { fixBulkDataURI } from './fixBulkDataURI';
|
||||
import {
|
||||
cleanDenaturalizedDataset,
|
||||
transferDenaturalizedDataset,
|
||||
} from './cleanDenaturalizedDataset';
|
||||
|
||||
export { fixBulkDataURI };
|
||||
export { fixMultiValueKeys } from './fixMultiValueKeys';
|
||||
|
||||
export { fixBulkDataURI, cleanDenaturalizedDataset, transferDenaturalizedDataset };
|
||||
Reference in new issue
Block a user