feat(dicomJSON): Add Loading Other Display Sets and JSON Metadata Generation script (#3777)

This commit is contained in:
Alireza authored and GitHub committed 2023-11-10 16:51:23 -05:00
1 parent 5b513fd30e
commit 43b1c17209
9 files changed
+390 -3

No files matched your search

+66
View File
@@ -0,0 +1,66 @@
const handler = {
/**
* Get a proxied value from the array or property value
* Note that the property value get works even if you update the underlying object.
* Also, return true of proxy.__isProxy in order to distinguish proxies and not double proxy them.
*/
get: (target, prop) => {
if (prop == '__isProxy') {
return true;
}
if (prop in target) {
return target[prop];
}
return target[0][prop];
},
set: (obj, prop, value) => {
if (typeof prop === 'number' || prop in obj) {
obj[prop] = value;
} else {
obj[0][prop] = value;
}
return true;
},
};
/**
* Add a proxy object for sqZero or the src[0] element if sqZero is unspecified, AND
* src is an array of length 1.
*
* If sqZero isn't passed in, then assume this is a create call on the destination object
* itself, by:
* 1. If not an object, return dest
* 2. If an array of length != 1, return dest
* 3. If an array, use dest[0] as sqZero
* 4. Use dest as sqZero
*
* @example
* src = [{a:5,b:'string', c:null}]
* addAccessors(src)
* src.c = 'outerChange'
* src[0].b='innerChange'
*
* assert src.a===5
* assert src[0].c === 'outerChange'
* assert src.b === 'innerChange'
*/
const addAccessors = (dest, sqZero) => {
if (dest.__isProxy) {
return dest;
}
let itemZero = sqZero;
if (itemZero === undefined) {
if (typeof dest !== 'object') {
return dest;
}
if (Array.isArray(dest) && dest.length !== 1) {
return dest;
}
itemZero = Array.isArray(dest) ? dest[0] : dest;
}
const ret = [itemZero];
return new Proxy(ret, handler);
};
export default addAccessors;
+2
View File
@@ -27,6 +27,7 @@ import debounce from './debounce';
import roundNumber from './roundNumber';
import downloadCSVReport from './downloadCSVReport';
import isEqualWithin from './isEqualWithin';
import addAccessors from './addAccessors';
import {
sortStudy,
sortStudySeries,
@@ -65,6 +66,7 @@ const utils = {
Queue,
isDicomUid,
isEqualWithin,
addAccessors,
resolveObjectPath,
hierarchicalListUtils,
progressTrackingUtils,
+1
View File
@@ -40,6 +40,7 @@ describe('Top level exports', () => {
'progressTrackingUtils',
'subscribeToNextViewportGridChange',
'uuidv4',
'addAccessors',
].sort();
const exports = Object.keys(utils.default).sort();
@@ -28,6 +28,20 @@ dataset. Let's have a look at the JSON file:
JSON file stores the metadata for the study level, series level and instance
level. A JSON launch file should follow the same structure as the one below.
:::tip
You can use our script to generate the JSON file from a hosted endpoint. See
`.scripts/dicom-json-generator.js`
You could run it like this:
```bash
node .scripts/dicom-json-generator.js '/path/to/study/folder' 'url/to/dicom/server/folder' 'json/output/file.json'
```
Some modalities require additional metadata to be added to the JSON file. You can read more about the minimum amount of metadata required for the viewer to work [here](../../faq.md#what-are-the-list-of-required-metadata-for-the-ohif-viewer-to-work). We will handle this in the script. For example, the script will add the CodeSequences for SR in order to display the measurements in the viewer.
:::
Note that at the instance level metadata we are storing both the `metadata` and
also the `url` for the dicom file on the dicom server. In this case we are
referring to
@@ -35,6 +49,8 @@ referring to
which is stored in another directory in our s3. (You can actually try
downloading the dicom file by opening the url in your browser).
The URL to the script in the given example is `https://ohif-dicom-json-example.s3.amazonaws.com/LIDC-IDRI-0001/01-01-2000-30178`. This URL serves as the parent directory that contains all the series within their respective folders.
```json
{
"studies": [
+3 -1
View File
@@ -62,7 +62,9 @@ WorkList by adding the `dataSources` query parameter.
/?dataSources=orthanc
```
Note: you should pass the `sourceName` of the data source in the configuration file (not the friendly name nor the name)
Note1: You should pass the `sourceName` of the data source in the configuration file (not the friendly name nor the name)
Note2: Make sure that the configuration file you are using actually includes that data source. You cannot use a data source from another configuration file.
:::tip