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

[IDC-1994] Sort series list by SeriesNumber, and sort by same SeriesNumber by date/time. #2010

Merged
merged 4 commits into from
Aug 28, 2020
Merged
Show file tree
Hide file tree
Changes from 2 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
9 changes: 9 additions & 0 deletions extensions/dicom-html/src/OHIFDicomHtmlSopClassHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ const OHIFDicomHtmlSopClassHandler = {
getDisplaySetFromSeries(series, study, dicomWebClient, authorizationHeaders) {
const instance = series.getFirstInstance();

const {
SeriesDate,
SeriesTime,
SeriesNumber,
} = instance._instance.metadata;

return {
plugin: 'html',
Modality: 'SR',
Expand All @@ -31,6 +37,9 @@ const OHIFDicomHtmlSopClassHandler = {
SOPInstanceUID: instance.getSOPInstanceUID(),
SeriesInstanceUID: series.getSeriesInstanceUID(),
StudyInstanceUID: study.getStudyInstanceUID(),
SeriesDate,
SeriesTime,
SeriesNumber,
authorizationHeaders,
};
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ const DicomMicroscopySopClassHandler = {
getDisplaySetFromSeries(series, study, dicomWebClient) {
const instance = series.getFirstInstance();

const {
ContentDate,
ContentTime,
SeriesNumber,
} = instance._instance.metadata;

// Note: We are passing the dicomweb client into each viewport!

return {
Expand All @@ -22,6 +28,9 @@ const DicomMicroscopySopClassHandler = {
SOPInstanceUID: instance.getSOPInstanceUID(),
SeriesInstanceUID: series.getSeriesInstanceUID(),
StudyInstanceUID: study.getStudyInstanceUID(),
SeriesDate: ContentDate, // Map ContentDate/Time to SeriesTime for series list sorting.
SeriesTime: ContentTime,
SeriesNumber,
};
},
};
Expand Down
9 changes: 9 additions & 0 deletions extensions/dicom-pdf/src/OHIFDicomPDFSopClassHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ const OHIFDicomPDFSopClassHandler = {
getDisplaySetFromSeries(series, study, dicomWebClient, authorizationHeaders) {
const instance = series.getFirstInstance();

const {
ContentDate,
ContentTime,
SeriesNumber,
} = instance._instance.metadata;

return {
plugin: 'pdf',
Modality: 'DOC',
Expand All @@ -21,6 +27,9 @@ const OHIFDicomPDFSopClassHandler = {
SOPInstanceUID: instance.getSOPInstanceUID(),
SeriesInstanceUID: series.getSeriesInstanceUID(),
StudyInstanceUID: study.getStudyInstanceUID(),
SeriesDate: ContentDate, // Map ContentDate/Time to SeriesTime for series list sorting.
SeriesTime: ContentTime,
SeriesNumber,
authorizationHeaders: authorizationHeaders,
};
},
Expand Down
2 changes: 2 additions & 0 deletions extensions/dicom-rt/src/OHIFDicomRTStructSopClassHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const OHIFDicomRTStructSopClassHandler = {
const {
SeriesDate,
SeriesTime,
SeriesNumber,
SeriesDescription,
FrameOfReferenceUID,
SOPInstanceUID,
Expand All @@ -53,6 +54,7 @@ const OHIFDicomRTStructSopClassHandler = {
isLoaded: false,
SeriesDate,
SeriesTime,
SeriesNumber,
SeriesDescription,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default function getSopClassHandlerModule({ servicesManager }) {
const {
SeriesDate,
SeriesTime,
SeriesNumber,
SeriesDescription,
FrameOfReferenceUID,
SOPInstanceUID,
Expand All @@ -52,6 +53,7 @@ export default function getSopClassHandlerModule({ servicesManager }) {
isLoaded: false,
SeriesDate,
SeriesTime,
SeriesNumber,
SeriesDescription,
};

Expand Down
72 changes: 72 additions & 0 deletions platform/viewer/src/connectedComponents/Viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import UserManagerContext from '../context/UserManagerContext';
import AppContext from '../context/AppContext';

import './Viewer.css';
import { finished } from 'stream';

class Viewer extends Component {
static propTypes = {
Expand Down Expand Up @@ -189,6 +190,7 @@ class Viewer extends Component {
currentTimepointId,
]);
}

this.setState({
thumbnails: _mapStudiesToThumbnails(studies),
});
Expand All @@ -197,6 +199,7 @@ class Viewer extends Component {

componentDidUpdate(prevProps) {
const { studies, isStudyLoaded } = this.props;

if (studies !== prevProps.studies) {
this.setState({
thumbnails: _mapStudiesToThumbnails(studies),
Expand Down Expand Up @@ -365,18 +368,36 @@ const _mapStudiesToThumbnails = function(studies) {
return studies.map(study => {
const { StudyInstanceUID } = study;

let finishedProcessing = true;

const thumbnails = study.displaySets.map(displaySet => {
const {
displaySetInstanceUID,
SeriesDescription,
SeriesNumber,
InstanceNumber,
numImageFrames,
SeriesDate,
SeriesTime,
} = displaySet;

let imageId;
let altImageText;

let seriesDateTime = '';

if (SeriesDate) {
if (SeriesTime) {
seriesDateTime = `${SeriesDate}${SeriesTime}`;
} else {
seriesDateTime = `${SeriesDate}$`;
}
}

if (!displaySet.hasOwnProperty('SeriesDate')) {
JamesAPetts marked this conversation as resolved.
Show resolved Hide resolved
finishedProcessing = false;
}

if (displaySet.Modality && displaySet.Modality === 'SEG') {
// TODO: We want to replace this with a thumbnail showing
// the segmentation map on the image, but this is easier
Expand All @@ -398,12 +419,63 @@ const _mapStudiesToThumbnails = function(studies) {
SeriesNumber,
InstanceNumber,
numImageFrames,
seriesDateTime,
};
});

// Only sort if we have processed all displaySets, or this can be exceedingly slow whilst each is being created.

if (finishedProcessing) {
// Sort by SeriesNumber && SeriesDate/SeriesTime for the same SeriesNumber.
thumbnails.sort((a, b) => a.SeriesNumber - b.SeriesNumber);

_sortSameSeriesNumberByDateTime(thumbnails);
}

return {
StudyInstanceUID,
thumbnails,
};
});
};

function _sortSameSeriesNumberByDateTime(thumbnails) {
if (!thumbnails.length) {
return;
}

let currentSeriesNumber = thumbnails[0].SeriesNumber;
let initialIndex = 0;

// Start from 1 as we intiialise with the details of index zero.
for (let i = 1; i < thumbnails.length; i++) {
const { SeriesNumber } = thumbnails[i];

if (currentSeriesNumber !== SeriesNumber) {
// When the series number changes:

if (i - 1 > initialIndex) {
// Sort initialIndex to i -1;
sortSubArrayBtDateTime(thumbnails, initialIndex, i - 1);
}

initialIndex = i;
currentSeriesNumber = SeriesNumber;
}
}

// Deal with the end of the list if the last N items have the same SeriesNumber
if (thumbnails.length - 1 > initialIndex) {
sortSubArrayBtDateTime(thumbnails, initialIndex, thumbnails.length - 1);
}
}

function sortSubArrayBtDateTime(thumbnails, initialIndex, lastIndex) {
const subArray = thumbnails.splice(
initialIndex,
lastIndex - initialIndex + 1
);

subArray.sort((a, b) => b.seriesDateTime - a.seriesDateTime);
thumbnails.splice(initialIndex, 0, ...subArray);
}