ohif-viewer/docs/latest/services/data/MeasurementService.md
Alireza 5643f8f6d2
feat: Added documentation for OHIF-v3 (#2450)
* Added docs with new screenshots

* Added doc to architecture

* Added documentations to various extension modules

* Added more documentation to modes

* Added docs to managers

* Added docs for services

* Fixed deployment docs

* Added white labelling documentation

* Added i18n docs and measurement export
2021-06-15 11:15:29 -04:00

157 lines
5.3 KiB
Markdown

# Measurement Service
## Overview
`MeasurementService` handles the internal measurement representation inside `OHIF` platform.
Developers can add their custom `sources` with `mappers` to enable adding measurements inside OHIF.
Currently, we are maintaining `CornerstoneTools` annotations and corresponding mappers can be found
inside the `cornerstone` extension. However, `MeasurementService` can be configured to work with any
custom tools given that its `mappers` is added to the `MeasurementService`.
We can see the overall architecture of the `MeasurementService` below:
![services-measurements](../../assets/img/services-measurements.png)
## Events
There are seven events that get publish in `MeasurementService`:
| Event | Description |
| --------------------- | ------------------------------------------------------ |
| MEASUREMENT_UPDATED | Fires when a measurement is updated |
| MEASUREMENT_ADDED | Fires when a new measurement is added |
| RAW_MEASUREMENT_ADDED | Fires when a raw measurement is added (e.g., dicom-sr) |
| MEASUREMENT_REMOVED | Fires when a measurement is removed |
| MEASUREMENTS_CLEARED | Fires when all measurements are deleted |
| JUMP_TO_MEASUREMENT | Fires when a measurement is requested to be jump to |
## API
- `getMeasurements`: returns array of measurements
- `getMeasurement(id)`: returns the corresponding measurement based on the provided Id.
- `remove(id, source)`: removes a measurement and broadcasts the `MEASUREMENT_REMOVED` event.
- `clearMeasurements`: removes all measurements and broadcasts `MEASUREMENTS_CLEARED` event.
- `createSource(name, version)`: creates a new measurement source, generates a uid and adds it to the `sources` property of the service.
- `addMapping(source, definition, matchingCriteria, toSourceSchema, toMeasurementSchema)`: adds a new measurement matching criteria along with mapping functions.
We will learn more about [source/mappers below](#source--mappers)
- `update`: updates the measurement details and fires `MEASUREMENT_UPDATED`
- `addRawMeasurement(source,definition,data,toMeasurementSchema,dataSource = {}` : adds a raw measurement into a source so that it may be
converted to/from annotation in the same way. E.g. import serialized data
of the same form as the measurement source. Fires `MEASUREMENT_UPDATED` or `MEASUREMENT_ADDED`.
Note that, `MeasurementService` handles finding the correct mapper upon new measurements; however, `addRawMeasurement` provides more flexibility.
You can take a look into its usage in `dicom-sr` extension.
- `source`: The measurement source instance.
- `definition`: The source definition you want to add the measurement to.
- `data`: The data you wish to add to the source.
- `toMeasurementSchema`: A function to get the `data` into the same shape as the source definition.
- `jumpToMeasurement(viewportIndex, id)`: calls the listeners who have subscribed to `JUMP_TO_MEASUREMENT`.
## Source / Mappers
To create a custom measurement source and relevant mappers for each tool, you can take a look
at the `init.js` inside the `cornerstone` extension. In which we are registering our
`CornerstoneTools-v4` measurement source to MeasurementService. Let's take a peek at the
*simplified* implementation together. To achieve this, for each tool, we need to
provide three mappers:
- `matchingCriteria`: criteria used for finding the correct mapper for the drawn tool.
- `toAnnotation`: tbd
- `toMeasurement`: a function that converts the tool data to OHIF internal representation of measurement data.
```js
// extensions/cornerstone/src/utils/measurementServiceMappings/Length.js
function toMeasurement(
csToolsAnnotation,
DisplaySetService,
getValueTypeFromToolType
) {
const { element, measurementData } = csToolsAnnotation
/** ... **/
const {
SOPInstanceUID,
FrameOfReferenceUID,
SeriesInstanceUID,
StudyInstanceUID,
} = getSOPInstanceAttributes(element)
const displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
SOPInstanceUID,
SeriesInstanceUID
)
/** ... **/
return {
id: measurementData.id,
SOPInstanceUID,
FrameOfReferenceUID,
referenceSeriesUID: SeriesInstanceUID,
referenceStudyUID: StudyInstanceUID,
displaySetInstanceUID: displaySet.displaySetInstanceUID,
label: measurementData.label,
description: measurementData.description,
unit: measurementData.unit,
length: measurementData.length,
type: getValueTypeFromToolType(tool),
points: getPointsFromHandles(measurementData.handles),
}
}
//////////////////////////////////////////
// extensions/cornerstone/src/init.js
const Length = {
toAnnotation,
toMeasurement,
matchingCriteria: [
{
valueType: MeasurementService.VALUE_TYPES.POLYLINE,
points: 2,
},
],
}
const _initMeasurementService = (MeasurementService, DisplaySetService) => {
/** ... **/
const csToolsVer4MeasurementSource = MeasurementService.createSource(
'CornerstoneTools',
'4'
);
/* Mappings */
MeasurementService.addMapping(
csToolsVer4MeasurementSource,
'Length',
Length.matchingCriteria,
toAnnotation,
toMeasurement
);
/** Other tools **/
return csToolsVer4MeasurementSource;
};
```