Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | 77x 77x 77x 77x 77x 77x 77x 77x 77x 11852x 19114x 19114x 14524x 14524x 14354x 170x 119x 119x 170x 77x 7409x 7409x 300754x 300754x 300754x 11852x 77x 447x 447x 447x 447x 447x 433x 658x 14x 14x 14x 14x 658x 658x 658x 14x 14x 7x 329x 7x | import { DicomMetadataStore, classes } from '@ohif/core';
import { calculateSUVScalingFactors } from '@cornerstonejs/calculate-suv';
import getPTImageIdInstanceMetadata from './getPTImageIdInstanceMetadata';
import { registerHangingProtocolAttributes } from './hangingprotocols';
import { HotkeysManager } from '@ohif/core';
const metadataProvider = classes.MetadataProvider;
/**
*
* @param {Object} servicesManager
* @param {Object} configuration
*/
export default function init({
servicesManager,
commandsManager,
hotkeysManager,
}: withAppTypes): void {
const { toolbarService, cineService, viewportGridService } = servicesManager.services;
toolbarService.registerEventForToolbarUpdate(cineService, [
cineService.EVENTS.CINE_STATE_CHANGED,
]);
toolbarService.registerEventForToolbarUpdate(hotkeysManager, [
HotkeysManager.EVENTS.HOTKEY_PRESSED,
]);
// Add
DicomMetadataStore.subscribe(DicomMetadataStore.EVENTS.INSTANCES_ADDED, handleScalingModules);
// 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, handleScalingModules);
// 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 eventSubscriptions = [];
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)) {
const subscriptionKey = `${event}_${JSON.stringify(commands)}`;
if (eventSubscriptions.includes(subscriptionKey)) {
return;
}
viewportGridService.subscribe(event, eventData => {
const viewportId = eventData?.viewportId ?? viewportGridService.getActiveViewportId();
commandsManager.run(commands, { viewportId });
});
eventSubscriptions.push(subscriptionKey);
}
});
};
toolbarService.subscribe(toolbarService.EVENTS.TOOL_BAR_MODIFIED, state => {
const { buttons } = state;
for (const [id, button] of Object.entries(buttons)) {
const { buttonSection, items, listeners } = button.props || {};
// Handle group items' listeners
Iif (buttonSection && items) {
items.forEach(item => {
Iif (item.listeners) {
subscribeToEvents(item.listeners);
}
});
}
// Handle button listeners
if (listeners) {
subscribeToEvents(listeners);
}
}
});
}
const handleScalingModules = ({ SeriesInstanceUID, StudyInstanceUID }) => {
const { instances } = DicomMetadataStore.getSeries(StudyInstanceUID, SeriesInstanceUID);
Iif (!instances?.length) {
return;
}
const modality = instances[0].Modality;
const allowedModality = ['PT', 'RTDOSE'];
if (!allowedModality.includes(modality)) {
return;
}
const imageIds = instances.map(instance => instance.imageId);
const instanceMetadataArray = [];
Iif (modality === 'RTDOSE') {
const DoseGridScaling = instances[0].DoseGridScaling;
const DoseSummation = instances[0].DoseSummation;
const DoseType = instances[0].DoseType;
const DoseUnit = instances[0].DoseUnit;
const NumberOfFrames = instances[0].NumberOfFrames;
const imageId = imageIds[0];
// add scaling module to the metadata
// since RTDOSE is always a multiframe we should add the scaling module to each frame
for (let i = 0; i < NumberOfFrames; i++) {
const frameIndex = i + 1;
// Todo: we should support other things like wadouri, local etc
const newImageId = `${imageId.replace(/\/frames\/\d+$/, '')}/frames/${frameIndex}`;
metadataProvider.addCustomMetadata(newImageId, 'scalingModule', {
DoseGridScaling,
DoseSummation,
DoseType,
DoseUnit,
});
}
return;
}
// 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);
}
});
Iif (!instanceMetadataArray.length) {
return;
}
const suvScalingFactors = calculateSUVScalingFactors(instanceMetadataArray);
instanceMetadataArray.forEach((instanceMetadata, index) => {
metadataProvider.addCustomMetadata(
imageIds[index],
'scalingModule',
suvScalingFactors[index]
);
});
} catch (error) {
console.log(error);
}
};
|