# Module: SOP Class Handler An extension can register a [SOP Class][sop-class-link] Handler Module by defining a `getSopClassHandlerModule` method. The [SOP Class][sop-class-link] Handler is a bit different from the other modules, as it doesn't provide a `1:1` schema for UI or provide it's own components. It instead defines: - `sopClassUIDs`: an array of string SOP Class UIDs that the `getDisplaySetFromSeries` method should be applied to. - `getDisplaySetFromSeries`: a method that maps series and study metadata to a display set A `displaySet` has the following shape: ```js return { plugin: 'html', Modality: 'SR', displaySetInstanceUID: 0, wadoRoot: study.getData().wadoRoot, wadoUri: instance.getData().wadouri, SOPInstanceUID: instance.getSOPInstanceUID(), SeriesInstanceUID: series.getSeriesInstanceUID(), StudyInstanceUID: study.getStudyInstanceUID(), authorizationHeaders, }; ``` Where the `plugin` key is used to influence the default `ViewportComponent` for rendering the `displaySet`. Additional properties are passed to the `ViewportComponent` and used by the default `StudyBrowser` to render "thumbnails" for each `displaySet` ## Example SOP Class Handler Module ```js const SOP_CLASS_UIDS = { BASIC_TEXT_SR: '1.2.840.10008.5.1.4.1.1.88.11', ENHANCED_SR: '1.2.840.10008.5.1.4.1.1.88.22', }; export default { id: 'example-sop-class-handler-module', /** * @param {object} params * @param {ServicesManager} params.servicesManager * @param {CommandsManager} params.commandsManager */ getSopClassHandlerModule({ servicesManager, commandsManager }) { return { id: 'OHIFDicomHtmlSopClassHandler', sopClassUIDs: Object.values(SOP_CLASS_UIDS), /** * @param {object} series - * @param {object} study - * @param {object} dicomWebClient - * @param {object} authorizationHeaders - */ getDisplaySetFromSeries(series, study, dicomWebClient, authorizationHeaders) { const instance = series.getFirstInstance(); return { plugin: 'html', displaySetInstanceUID: 0, wadoRoot: study.getData().wadoRoot, wadoUri: instance.getData().wadouri, SOPInstanceUID: instance.getSOPInstanceUID(), SeriesInstanceUID: series.getSeriesInstanceUID(), StudyInstanceUID: study.getStudyInstanceUID(), authorizationHeaders, }; }, } }; ``` ### More examples : - [Dicom-HTML SOP][dicom-html-sop] - [Dicom-PDF SOP][dicom-pdf-sop] - [Dicom-Microscopy SOP][dicom-micro-sop] - [Dicom-Segmentation SOP][dicom-seg-sop] ## `@ohif/viewer` usage We use the `sopClassHandlerModule`s in three different places: - `ViewerLocalFileData.js` - `ViewerRetrieveStudyData.js` - `StandaloneRouting.js` Each time, it is used to map study and series data to `displaySets`. It does this by working alongside the `StudyMetadataManager` in `@ohif/core`. That manager has the method `createDisplaySets` that takes an array of `sopClassHandlerModules`. [sop-class-link]: http://dicom.nema.org/dicom/2013/output/chtml/part04/sect_B.5.html [dicom-html-sop]: https://github.com/OHIF/Viewers/blob/master/extensions/dicom-html/src/OHIFDicomHtmlSopClassHandler.js#L4-L12 [dicom-pdf-sop]: https://github.com/OHIF/Viewers/blob/master/extensions/dicom-pdf/src/OHIFDicomPDFSopClassHandler.js#L4-L6 [dicom-micro-sop]: https://github.com/OHIF/Viewers/blob/master/extensions/dicom-microscopy/src/DicomMicroscopySopClassHandler.js#L5-L7 [dicom-seg-sop]: https://github.com/OHIF/Viewers/blob/master/extensions/dicom-segmentation/src/OHIFDicomSegSopClassHandler.js#L5-L7