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

Re IDC #3077: Seg series thumbnail selection #3078

Merged
merged 3 commits into from
Jan 17, 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
100 changes: 100 additions & 0 deletions extensions/dicom-segmentation/src/commandsModule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import csTools from 'cornerstone-tools';
import cs from 'cornerstone-core';
import OHIF from '@ohif/core';

import DICOMSegTempCrosshairsTool from './tools/DICOMSegTempCrosshairsTool';
import refreshViewports from './utils/refreshViewports';

const { studyMetadataManager } = OHIF.utils;

const commandsModule = ({ commandsManager }) => {
const actions = {
jumpToFirstSegment: ({ viewports }) => {
try {
const { activeViewportIndex, viewportSpecificData } = viewports;
const viewport = viewportSpecificData[activeViewportIndex];
const { StudyInstanceUID, displaySetInstanceUID } = viewport;
const studyMetadata = studyMetadataManager.get(StudyInstanceUID);
const firstImageId = studyMetadata.getFirstImageId(
displaySetInstanceUID
);

const module = csTools.getModule('segmentation');
const brushStackState = module.state.series[firstImageId];
const { labelmaps3D, activeLabelmapIndex } = brushStackState;
const { labelmaps2D } = labelmaps3D[activeLabelmapIndex];

const firstLabelMap2D = labelmaps2D.find(value => !!value);
const firstSegment = firstLabelMap2D.segmentsOnLabelmap[0];
const segmentNumber = firstSegment;

const validIndexList = [];
labelmaps2D.forEach((labelMap2D, index) => {
if (labelMap2D.segmentsOnLabelmap.includes(segmentNumber)) {
validIndexList.push(index);
}
});

const avg = array => array.reduce((a, b) => a + b) / array.length;
const average = avg(validIndexList);
const closest = validIndexList.reduce((prev, curr) => {
return Math.abs(curr - average) < Math.abs(prev - average)
? curr
: prev;
});

const enabledElements = cs.getEnabledElements();
const element = enabledElements[activeViewportIndex].element;

const toolState = csTools.getToolState(element, 'stack');
if (!toolState) return;

const imageIds = toolState.data[0].imageIds;
const imageId = imageIds[closest];
const frameIndex = imageIds.indexOf(imageId);
const SOPInstanceUID = cs.metaData.get('SOPInstanceUID', imageId);

cs.getEnabledElements().forEach(enabledElement => {
cs.updateImage(enabledElement.element);
});

DICOMSegTempCrosshairsTool.addCrosshair(
element,
imageId,
segmentNumber
);

cs.getEnabledElements().forEach(enabledElement => {
cs.updateImage(enabledElement.element);
});

const refreshViewports = false;

commandsManager.runCommand('jumpToImage', {
StudyInstanceUID,
SOPInstanceUID,
frameIndex,
activeViewportIndex,
refreshViewports,
});
} catch (error) {
console.log('Error in moving to the first segment slice');
}
},
};

const definitions = {
jumpToFirstSegment: {
commandFn: actions.jumpToFirstSegment,
storeContexts: ['viewports'],
options: {},
},
};

return {
definitions,
defaultContext: 'VIEWER',
};
};

export default commandsModule;
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,32 @@ const SegmentationSettings = ({ configuration, onBack, onChange, servicesManager
setState(state => ({ ...state, [field]: value }));
};

const once = fn => (...args) => {
if (!fn) return;
fn(...args);
fn = null;
};

const segTolValue = document.getElementById('segToleranceValue');
if (segTolValue) {
segTolValue.onchange = once(function() {
const { UINotificationService, LoggerService } = servicesManager.services;

const error = new Error(
'Segmentation loader tolerance changed.\
This operation can potentially generate errors in the Segmentation parsing.'
);

LoggerService.error({ error, message: error.message });
UINotificationService.show({
title: 'Segmentation panel',
message: error.message,
type: 'warning',
autoClose: true,
});
});
}

const toFloat = value => parseFloat(value / 100).toFixed(2);

return (
Expand Down Expand Up @@ -138,32 +164,23 @@ const SegmentationSettings = ({ configuration, onBack, onChange, servicesManager
<label style={{ margin: '0 15px' }}>
Tolerance:
<input
id="segToleranceValue"
style={{ margin: '0 15px' }}
label="Tolerance"
onKeyPress={event => {
const validate = string => {
let rgx = /[^-.e0-9]+/g;
return string.match(rgx);
};
const validate = string => {
let rgx = /[^-.e0-9]+/g;
return string.match(rgx);
};

if (validate(event.key)) {
event.preventDefault();
if (validate(event.key)) {
event.preventDefault();
}
}
}}
}
onChange={event => {
save('segsTolerance', event.target.value);

const { UINotificationService, LoggerService } = servicesManager.services;
const error = new Error('Segmentation loader tolerance changed. This operation can potentially generate errors in the Segmentation parsing.');
LoggerService.error({ error, message: error.message });
UINotificationService.show({
title: 'Segmentation panel',
message: error.message,
type: 'warning',
autoClose: true,
});
}
}
}}
value={state.segsTolerance}
/>
</label>
Expand Down
13 changes: 13 additions & 0 deletions extensions/dicom-segmentation/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import toolbarModule from './toolbarModule.js';
import getSopClassHandlerModule from './getOHIFDicomSegSopClassHandler.js';
import SegmentationPanel from './components/SegmentationPanel/SegmentationPanel.js';
import { version } from '../package.json';
import commandsModule from './commandsModule.js';
const { studyMetadataManager } = OHIF.utils;

export default {
Expand Down Expand Up @@ -121,6 +122,15 @@ export default {
});
};

const onSegmentationsCompletelyLoaded = () => {
commandsManager.runCommand('jumpToFirstSegment');
};

document.addEventListener(
'segseriesselected',
onSegmentationsCompletelyLoaded
);

document.addEventListener(
'extensiondicomsegmentationsegloaded',
onSegmentationsLoaded
Expand Down Expand Up @@ -182,5 +192,8 @@ export default {
defaultContext: ['VIEWER'],
};
},
getCommandsModule({ commandsManager, servicesManager }) {
return commandsModule({ commandsManager, servicesManager });
},
getSopClassHandlerModule,
};
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ const mapDispatchToProps = (dispatch, ownProps) => {
detail: { activatedLabelmapIndex: activatedLabelmapIndex },
}
);
const segThumbnailSelected = new CustomEvent('segseriesselected');
document.dispatchEvent(selectionFired);
document.dispatchEvent(segThumbnailSelected);
});
} else if (Modality !== 'SR') {
displaySet = displaySet.getSourceDisplaySet(ownProps.studyMetadata);
Expand Down
10 changes: 5 additions & 5 deletions platform/viewer/src/connectedComponents/Viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -505,14 +505,14 @@ const _checkForDerivedDisplaySets = async function(displaySet, study) {
* @returns {[string]} an array of strings containing the warnings
*/
const _checkForSeriesInconsistencesWarnings = async function(displaySet) {
if (displaySet.inconsistencyWarnings) {
// warnings already checked and cached in displaySet
return displaySet.inconsistencyWarnings;
}

const inconsistencyWarnings = [];

if (displaySet.Modality !== 'SEG') {
// warnings already checked and cached in displaySet
if (displaySet.inconsistencyWarnings) {
return displaySet.inconsistencyWarnings;
}

if (
displaySet.reconstructionIssues &&
displaySet.reconstructionIssues.length !== 0
Expand Down