feat(SR): SCOORD3D point annotations support for stack viewports (#4315)
This commit is contained in:
1 parent
e0fca8c88c
commit
ac1cad25af
51 files changed
+978
-607
No files matched your search
+59
-61
@@ -4,11 +4,12 @@ import { StudySummary, MeasurementTable, useViewportGrid, ActionButtons } from '
|
||||
import { DicomMetadataStore, utils } from '@ohif/core';
|
||||
import { useDebounce } from '@hooks';
|
||||
import { useAppConfig } from '@state';
|
||||
import { useTrackedMeasurements } from '../../getContextModule';
|
||||
import debounce from 'lodash.debounce';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Separator } from '@ohif/ui-next';
|
||||
|
||||
import { useTrackedMeasurements } from '../../getContextModule';
|
||||
|
||||
const { downloadCSVReport } = utils;
|
||||
const { formatDate } = utils;
|
||||
|
||||
@@ -43,49 +44,50 @@ function PanelMeasurementTableTracking({
|
||||
|
||||
useEffect(() => {
|
||||
const measurements = measurementService.getMeasurements();
|
||||
const filteredMeasurements = measurements.filter(
|
||||
m => trackedStudy === m.referenceStudyUID && trackedSeries.includes(m.referenceSeriesUID)
|
||||
);
|
||||
|
||||
const mappedMeasurements = filteredMeasurements.map(m =>
|
||||
_mapMeasurementToDisplay(m, measurementService.VALUE_TYPES, displaySetService)
|
||||
const mappedMeasurements = measurements.map(m =>
|
||||
_mapMeasurementToDisplay(m, displaySetService)
|
||||
);
|
||||
setDisplayMeasurements(mappedMeasurements);
|
||||
// eslint-ignore-next-line
|
||||
}, [measurementService, trackedStudy, trackedSeries, debouncedMeasurementChangeTimestamp]);
|
||||
|
||||
const updateDisplayStudySummary = async () => {
|
||||
if (trackedMeasurements.matches('tracking')) {
|
||||
const StudyInstanceUID = trackedStudy;
|
||||
const studyMeta = DicomMetadataStore.getStudy(StudyInstanceUID);
|
||||
const instanceMeta = studyMeta.series[0].instances[0];
|
||||
const { StudyDate, StudyDescription } = instanceMeta;
|
||||
|
||||
const modalities = new Set();
|
||||
studyMeta.series.forEach(series => {
|
||||
if (trackedSeries.includes(series.SeriesInstanceUID)) {
|
||||
modalities.add(series.instances[0].Modality);
|
||||
}
|
||||
});
|
||||
const modality = Array.from(modalities).join('/');
|
||||
|
||||
if (displayStudySummary.key !== StudyInstanceUID) {
|
||||
setDisplayStudySummary({
|
||||
key: StudyInstanceUID,
|
||||
date: StudyDate, // TODO: Format: '07-Sep-2010'
|
||||
modality,
|
||||
description: StudyDescription,
|
||||
});
|
||||
}
|
||||
} else if (trackedStudy === '' || trackedStudy === undefined) {
|
||||
setDisplayStudySummary(DISPLAY_STUDY_SUMMARY_INITIAL_VALUE);
|
||||
}
|
||||
};
|
||||
}, [
|
||||
measurementService,
|
||||
displaySetService,
|
||||
trackedStudy,
|
||||
trackedSeries,
|
||||
debouncedMeasurementChangeTimestamp,
|
||||
]);
|
||||
|
||||
// ~~ DisplayStudySummary
|
||||
useEffect(() => {
|
||||
const updateDisplayStudySummary = async () => {
|
||||
if (trackedMeasurements.matches('tracking')) {
|
||||
const StudyInstanceUID = trackedStudy;
|
||||
const studyMeta = DicomMetadataStore.getStudy(StudyInstanceUID);
|
||||
const instanceMeta = studyMeta.series[0].instances[0];
|
||||
const { StudyDate, StudyDescription } = instanceMeta;
|
||||
|
||||
const modalities = new Set();
|
||||
studyMeta.series.forEach(series => {
|
||||
if (trackedSeries.includes(series.SeriesInstanceUID)) {
|
||||
modalities.add(series.instances[0].Modality);
|
||||
}
|
||||
});
|
||||
const modality = Array.from(modalities).join('/');
|
||||
|
||||
if (displayStudySummary.key !== StudyInstanceUID) {
|
||||
setDisplayStudySummary({
|
||||
key: StudyInstanceUID,
|
||||
date: StudyDate, // TODO: Format: '07-Sep-2010'
|
||||
modality,
|
||||
description: StudyDescription,
|
||||
});
|
||||
}
|
||||
} else if (trackedStudy === '' || trackedStudy === undefined) {
|
||||
setDisplayStudySummary(DISPLAY_STUDY_SUMMARY_INITIAL_VALUE);
|
||||
}
|
||||
};
|
||||
updateDisplayStudySummary();
|
||||
}, [displayStudySummary.key, trackedMeasurements, trackedStudy, updateDisplayStudySummary]);
|
||||
}, [displayStudySummary.key, trackedSeries, trackedMeasurements, trackedStudy]);
|
||||
|
||||
// TODO: Better way to consolidated, debounce, check on change?
|
||||
// Are we exposing the right API for measurementService?
|
||||
@@ -125,13 +127,11 @@ function PanelMeasurementTableTracking({
|
||||
const trackedMeasurements = measurements.filter(
|
||||
m => trackedStudy === m.referenceStudyUID && trackedSeries.includes(m.referenceSeriesUID)
|
||||
);
|
||||
|
||||
downloadCSVReport(trackedMeasurements, measurementService);
|
||||
downloadCSVReport(trackedMeasurements);
|
||||
}
|
||||
|
||||
const jumpToImage = ({ uid, isActive }) => {
|
||||
measurementService.jumpToMeasurement(viewportGrid.activeViewportId, uid);
|
||||
|
||||
onMeasurementItemClickHandler({ uid, isActive });
|
||||
};
|
||||
|
||||
@@ -160,7 +160,6 @@ function PanelMeasurementTableTracking({
|
||||
if (!isActive) {
|
||||
const measurements = [...displayMeasurements];
|
||||
const measurement = measurements.find(m => m.uid === uid);
|
||||
|
||||
measurements.forEach(m => (m.isActive = m.uid !== uid ? false : true));
|
||||
measurement.isActive = true;
|
||||
setDisplayMeasurements(measurements);
|
||||
@@ -168,14 +167,25 @@ function PanelMeasurementTableTracking({
|
||||
};
|
||||
|
||||
const displayMeasurementsWithoutFindings = displayMeasurements.filter(
|
||||
dm => dm.measurementType !== measurementService.VALUE_TYPES.POINT && dm.referencedImageId
|
||||
dm =>
|
||||
dm.measurementType !== measurementService.VALUE_TYPES.POINT &&
|
||||
dm.referencedImageId &&
|
||||
trackedStudy === dm.referenceStudyUID &&
|
||||
trackedSeries.includes(dm.referenceSeriesUID)
|
||||
);
|
||||
const additionalFindings = displayMeasurements.filter(
|
||||
dm => dm.measurementType === measurementService.VALUE_TYPES.POINT && dm.referencedImageId
|
||||
dm =>
|
||||
dm.measurementType === measurementService.VALUE_TYPES.POINT &&
|
||||
dm.referencedImageId &&
|
||||
trackedStudy === dm.referenceStudyUID &&
|
||||
trackedSeries.includes(dm.referenceSeriesUID)
|
||||
);
|
||||
const nonAcquisitionMeasurements = displayMeasurements.filter(
|
||||
dm =>
|
||||
dm.referencedImageId == null ||
|
||||
trackedStudy !== dm.referenceStudyUID ||
|
||||
trackedSeries.includes(dm.referenceSeriesUID)
|
||||
);
|
||||
|
||||
const nonAcquisitionMeasurements = displayMeasurements.filter(dm => dm.referencedImageId == null);
|
||||
|
||||
const disabled =
|
||||
additionalFindings.length === 0 &&
|
||||
displayMeasurementsWithoutFindings.length === 0 &&
|
||||
@@ -278,23 +288,11 @@ PanelMeasurementTableTracking.propTypes = {
|
||||
};
|
||||
|
||||
// TODO: This could be a measurementService mapper
|
||||
function _mapMeasurementToDisplay(measurement, types, displaySetService) {
|
||||
const { referenceStudyUID, referenceSeriesUID, SOPInstanceUID } = measurement;
|
||||
function _mapMeasurementToDisplay(measurement, displaySetService) {
|
||||
const { referenceSeriesUID } = measurement;
|
||||
|
||||
// TODO: We don't deal with multiframe well yet, would need to update
|
||||
// This in OHIF-312 when we add FrameIndex to measurements.
|
||||
|
||||
const instance = DicomMetadataStore.getInstance(
|
||||
referenceStudyUID,
|
||||
referenceSeriesUID,
|
||||
SOPInstanceUID
|
||||
);
|
||||
|
||||
const displaySets = displaySetService.getDisplaySetsForSeries(referenceSeriesUID);
|
||||
|
||||
if (!displaySets[0]?.instances) {
|
||||
throw new Error('The tracked measurements panel should only be tracking "stack" displaySets.');
|
||||
}
|
||||
// This in OHIF-312 when we add FrameIndex to measurements
|
||||
|
||||
const {
|
||||
displayText: baseDisplayText,
|
||||
|
||||
Reference in new issue
Block a user