114 lines
3.4 KiB
TypeScript
114 lines
3.4 KiB
TypeScript
import { DicomMetadataStore, classes } from '@ohif/core';
|
|
import { calculateSUVScalingFactors } from '@cornerstonejs/calculate-suv';
|
|
|
|
import getPTImageIdInstanceMetadata from './getPTImageIdInstanceMetadata';
|
|
import { registerHangingProtocolAttributes } from './hangingprotocols';
|
|
|
|
const metadataProvider = classes.MetadataProvider;
|
|
|
|
/**
|
|
*
|
|
* @param {Object} servicesManager
|
|
* @param {Object} configuration
|
|
*/
|
|
export default function init({
|
|
servicesManager,
|
|
configuration = {},
|
|
commandsManager,
|
|
}: withAppTypes): void {
|
|
const { toolbarService, cineService, viewportGridService } = servicesManager.services;
|
|
|
|
toolbarService.registerEventForToolbarUpdate(cineService, [
|
|
cineService.EVENTS.CINE_STATE_CHANGED,
|
|
]);
|
|
// Add
|
|
DicomMetadataStore.subscribe(DicomMetadataStore.EVENTS.INSTANCES_ADDED, handlePETImageMetadata);
|
|
|
|
// If the metadata for PET has changed by the user (e.g. manually changing the PatientWeight)
|
|
// we need to recalculate the SUV Scaling Factors
|
|
DicomMetadataStore.subscribe(DicomMetadataStore.EVENTS.SERIES_UPDATED, handlePETImageMetadata);
|
|
|
|
// Adds extra custom attributes for use by hanging protocols
|
|
registerHangingProtocolAttributes({ servicesManager });
|
|
|
|
// Function to process and subscribe to events for a given set of commands and listeners
|
|
const subscribeToEvents = listeners => {
|
|
Object.entries(listeners).forEach(([event, commands]) => {
|
|
const supportedEvents = [
|
|
viewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED,
|
|
viewportGridService.EVENTS.VIEWPORTS_READY,
|
|
];
|
|
|
|
if (supportedEvents.includes(event)) {
|
|
viewportGridService.subscribe(event, eventData => {
|
|
const viewportId = eventData?.viewportId ?? viewportGridService.getActiveViewportId();
|
|
|
|
commandsManager.run(commands, { viewportId });
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
toolbarService.subscribe(toolbarService.EVENTS.TOOL_BAR_MODIFIED, state => {
|
|
const { buttons } = state;
|
|
for (const [id, button] of Object.entries(buttons)) {
|
|
const { groupId, items, listeners } = button.props || {};
|
|
|
|
// Handle group items' listeners
|
|
if (groupId && items) {
|
|
items.forEach(item => {
|
|
if (item.listeners) {
|
|
subscribeToEvents(item.listeners);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Handle button listeners
|
|
if (listeners) {
|
|
subscribeToEvents(listeners);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
const handlePETImageMetadata = ({ SeriesInstanceUID, StudyInstanceUID }) => {
|
|
const { instances } = DicomMetadataStore.getSeries(StudyInstanceUID, SeriesInstanceUID);
|
|
|
|
if (!instances?.length) {
|
|
return;
|
|
}
|
|
|
|
const modality = instances[0].Modality;
|
|
|
|
if (!modality || modality !== 'PT') {
|
|
return;
|
|
}
|
|
|
|
const imageIds = instances.map(instance => instance.imageId);
|
|
const instanceMetadataArray = [];
|
|
// try except block to prevent errors when the metadata is not correct
|
|
try {
|
|
imageIds.forEach(imageId => {
|
|
const instanceMetadata = getPTImageIdInstanceMetadata(imageId);
|
|
if (instanceMetadata) {
|
|
instanceMetadataArray.push(instanceMetadata);
|
|
}
|
|
});
|
|
|
|
if (!instanceMetadataArray.length) {
|
|
return;
|
|
}
|
|
|
|
const suvScalingFactors = calculateSUVScalingFactors(instanceMetadataArray);
|
|
instanceMetadataArray.forEach((instanceMetadata, index) => {
|
|
metadataProvider.addCustomMetadata(
|
|
imageIds[index],
|
|
'scalingModule',
|
|
suvScalingFactors[index]
|
|
);
|
|
});
|
|
} catch (error) {
|
|
console.log(error);
|
|
}
|
|
};
|