Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adding support for multiframe metadata in wadors and wadouri #494

Merged
merged 19 commits into from
Jan 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"proseWrap": "always",
"tabWidth": 2,
"semi": true,
"singleQuote": true
"singleQuote": true,
"endOfLine":"auto"
}
83 changes: 83 additions & 0 deletions src/imageLoader/wadors/combineFrameInstance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import getTagValue from './getTagValue.js';

function getFrameInformation(
PerFrameFunctionalGroupsSequence,
SharedFunctionalGroupsSequence,
frameNumber
) {
const shared = (
SharedFunctionalGroupsSequence
? Object.values(SharedFunctionalGroupsSequence[0])
: []
)
.map((it) => it[0])
.filter((it) => it !== undefined && typeof it === 'object');
const perFrame = (
PerFrameFunctionalGroupsSequence
? Object.values(PerFrameFunctionalGroupsSequence[frameNumber - 1])
: []
)
.map((it) => it.Value[0])
.filter((it) => it !== undefined && typeof it === 'object');

return {
shared,
perFrame,
};
}

function getMultiframeInformation(metaData) {
let {
52009230: PerFrameFunctionalGroupsSequence,
52009229: SharedFunctionalGroupsSequence,
'00280008': NumberOfFrames,
// eslint-disable-next-line prefer-const
...rest
} = metaData;

PerFrameFunctionalGroupsSequence = getTagValue(
PerFrameFunctionalGroupsSequence,
false
);
SharedFunctionalGroupsSequence = getTagValue(
SharedFunctionalGroupsSequence,
false
);
NumberOfFrames = getTagValue(NumberOfFrames);

return {
PerFrameFunctionalGroupsSequence,
SharedFunctionalGroupsSequence,
NumberOfFrames,
rest,
};
}
// function that retrieves specific frame metadata information from multiframe
// metadata
function combineFrameInstance(frameNumber, instance) {
const {
PerFrameFunctionalGroupsSequence,
SharedFunctionalGroupsSequence,
NumberOfFrames,
rest,
} = getMultiframeInformation(instance);

if (PerFrameFunctionalGroupsSequence || NumberOfFrames > 1) {
const { shared, perFrame } = getFrameInformation(
PerFrameFunctionalGroupsSequence,
SharedFunctionalGroupsSequence,
frameNumber
);

return Object.assign(
rest,
{ '00280008': NumberOfFrames },
...Object.values(shared),
...Object.values(perFrame)
);
}

return instance;
}

export { combineFrameInstance, getMultiframeInformation, getFrameInformation };
11 changes: 11 additions & 0 deletions src/imageLoader/wadors/getTagValue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function getTagValue(tag, justElement = true) {
if (tag && tag.Value) {
if (tag.Value[0] && justElement) {
return tag.Value[0];
}

return tag.Value;
}

return tag;
}
16 changes: 16 additions & 0 deletions src/imageLoader/wadors/metaData/fixNMMetadata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import getTagValue from '../getTagValue.js';

export default function fixNMMetadata(metaData) {
if (!metaData['00200032'] || metaData['00200037']) {
// adjust metadata in case of multiframe NM data, as the dicom tags
// 00200032 and 00200037 could be found only in the dicom tag 00540022
const detectorInformationSequence = getTagValue(metaData['00540022']);

if (detectorInformationSequence) {
metaData['00200032'] = detectorInformationSequence['00200032'];
metaData['00200037'] = detectorInformationSequence['00200037'];
}
}

return metaData;
}
44 changes: 43 additions & 1 deletion src/imageLoader/wadors/metaData/metaDataProvider.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,53 @@
import external from '../../../externalModules.js';
import getNumberValues from './getNumberValues.js';
import getValue from './getValue.js';
import getNumberValue from './getNumberValue.js';
import getOverlayPlaneModule from './getOverlayPlaneModule.js';
import metaDataManager from '../metaDataManager.js';
import getValue from './getValue.js';
//import fixNMMetadata from './fixNMMetadata.js';
import {
getMultiframeInformation,
getFrameInformation,
} from '../combineFrameInstance.js';
import multiframeMetadata from '../retrieveMultiframeMetadata.js';

function metaDataProvider(type, imageId) {
if (type === 'multiframeModule') {
// the get function removes the PerFrameFunctionalGroupsSequence
const { metadata, frame } =
multiframeMetadata.retrieveMultiframeMetadata(imageId);

if (!metadata) {
return;
}
const {
PerFrameFunctionalGroupsSequence,
SharedFunctionalGroupsSequence,
NumberOfFrames,
} = getMultiframeInformation(metadata);

if (PerFrameFunctionalGroupsSequence || NumberOfFrames > 1) {
const { shared, perFrame } = getFrameInformation(
PerFrameFunctionalGroupsSequence,
SharedFunctionalGroupsSequence,
frame
);

return {
NumberOfFrames,
//PerFrameFunctionalGroupsSequence,
PerFrameFunctionalInformation: perFrame,
SharedFunctionalInformation: shared,
};
}

return {
NumberOfFrames,
//PerFrameFunctionalGroupsSequence,
};
}
const { dicomParser } = external;

const metaData = metaDataManager.get(imageId);

if (!metaData) {
Expand Down Expand Up @@ -38,6 +79,7 @@ function metaDataProvider(type, imageId) {
}

if (type === 'imagePlaneModule') {
//metaData = fixNMMetadata(metaData);
sedghi marked this conversation as resolved.
Show resolved Hide resolved
const imageOrientationPatient = getNumberValues(metaData['00200037'], 6);
const imagePositionPatient = getNumberValues(metaData['00200032'], 3);
const pixelSpacing = getNumberValues(metaData['00280030'], 2);
Expand Down
37 changes: 36 additions & 1 deletion src/imageLoader/wadors/metaDataManager.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,50 @@
import imageIdToURI from '../imageIdToURI.js';
import { combineFrameInstance } from './combineFrameInstance.js';
import multiframeMetadata from './retrieveMultiframeMetadata.js';

let metadataByImageURI = [];

function add(imageId, metadata) {
const imageURI = imageIdToURI(imageId);

metadata.isMultiframe = multiframeMetadata.isMultiframe(metadata);

metadataByImageURI[imageURI] = metadata;
}

// multiframes images will have only one imageid returned by the dicomweb
// client and registered in metadataByImageURI for all the n frames. If an
// iamgeid does not have metadata, or it does not have at all, or the imageid
// belongs to a frame, not registered in metadataByImageURI
function get(imageId) {
const imageURI = imageIdToURI(imageId);

return metadataByImageURI[imageURI];
// dealing first with the non multiframe information
let metadata = metadataByImageURI[imageURI];

if (metadata) {
if (!metadata.isMultiframe) {
return metadata;
}
}

let frame = 1;

if (!metadata) {
// in this case it could indicate a multiframe imageid
// Try to get the first frame metadata, where is stored the multiframe info
const firstFrameInfo =
multiframeMetadata._retrieveMultiframeMetadata(imageURI);

metadata = firstFrameInfo.metadata;
frame = firstFrameInfo.frame;
}

if (metadata) {
metadata = combineFrameInstance(frame, metadata);
}

return metadata;
}

function remove(imageId) {
Expand All @@ -24,6 +57,8 @@ function purge() {
metadataByImageURI = [];
}

export { metadataByImageURI };

export default {
add,
get,
Expand Down
39 changes: 39 additions & 0 deletions src/imageLoader/wadors/retrieveMultiframeMetadata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import getValue from './metaData/getValue.js';
import imageIdToURI from '../imageIdToURI.js';
import { metadataByImageURI } from './metaDataManager.js';

// get metadata information for the first frame
function _retrieveMultiframeMetadata(imageURI) {
const lastSlashIdx = imageURI.indexOf('/frames/') + 8;
// imageid string without frame number
const imageIdFrameless = imageURI.slice(0, lastSlashIdx);
// calculating frame number
const frame = parseInt(imageURI.slice(lastSlashIdx), 10);
// retrieving the frame 1 that contains multiframe information

const metadata = metadataByImageURI[`${imageIdFrameless}1`];

return {
metadata,
frame,
};
}

function retrieveMultiframeMetadata(imageId) {
const imageURI = imageIdToURI(imageId);

return _retrieveMultiframeMetadata(imageURI);
}

function isMultiframe(metadata) {
// Checks if dicomTag NumberOf Frames exists and it is greater than one
const numberOfFrames = getValue(metadata['00280008']);

return numberOfFrames && numberOfFrames > 1;
}

export default {
_retrieveMultiframeMetadata,
retrieveMultiframeMetadata,
isMultiframe,
};
Loading