Skip to content
Open
Show file tree
Hide file tree
Changes from 8 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
98 changes: 98 additions & 0 deletions src/utilities/MeasurementBuilder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import unit2CodingValue from "./TID300/unit2CodingValue";

class MeasurementBuilder {
static createNumericMeasurement(
codeValue,
codingScheme,
codeMeaning,
value,
unit,
annotationIndex
) {
return {
RelationshipType: "CONTAINS",
ValueType: "NUM",
ConceptNameCodeSequence: {
CodeValue: codeValue,
CodingSchemeDesignator: codingScheme,
CodeMeaning: codeMeaning
},
MeasuredValueSequence: {
MeasurementUnitsCodeSequence: unit2CodingValue(unit),
NumericValue: value
},
ContentSequence: {
RelationshipType: "INFERRED FROM",
ReferencedContentItemIdentifier: [1, 1, annotationIndex]
}
};
}

static createAreaMeasurement(area, areaUnit, annotationIndex) {
return MeasurementBuilder.createNumericMeasurement(
"G-A166",
"SRT",
"Area",
area,
areaUnit,
annotationIndex
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please provide documentation on what is annotationIndex

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doc string updated 096f2a3

);
}

static createRadiusMeasurement(radius, radiusUnit, annotationIndex) {
return MeasurementBuilder.createNumericMeasurement(
"131190003",
"SCT",
"Radius",
radius,
radiusUnit,
annotationIndex
);
}

static createMaxMeasurement(max, modalityUnit, annotationIndex) {
return MeasurementBuilder.createNumericMeasurement(
"56851009",
"SCT",
"Maximum",
max,
modalityUnit,
annotationIndex
);
}

static createMinMeasurement(min, modalityUnit, annotationIndex) {
return MeasurementBuilder.createNumericMeasurement(
"255605001",
"SCT",
"Minimum",
min,
modalityUnit,
annotationIndex
);
}

static createMeanMeasurement(mean, modalityUnit, annotationIndex) {
return MeasurementBuilder.createNumericMeasurement(
"373098007",
"SCT",
"Mean",
mean,
modalityUnit,
annotationIndex
);
}

static createStdDevMeasurement(stdDev, modalityUnit, annotationIndex) {
return MeasurementBuilder.createNumericMeasurement(
"386136009",
"SCT",
"Standard Deviation",
stdDev,
modalityUnit,
annotationIndex
);
}
}

export default MeasurementBuilder;
51 changes: 19 additions & 32 deletions src/utilities/TID300/Bidirectional.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import TID300Measurement from "./TID300Measurement.js";
import unit2CodingValue from "./unit2CodingValue.js";
import Tid320ContentItem from "./Tid320ContentItem.js";

export default class Bidirectional extends TID300Measurement {
contentItem() {
Expand All @@ -23,6 +24,22 @@ export default class Bidirectional extends TID300Measurement {
use3DSpatialCoordinates
});

const longAxisContentSequence = new Tid320ContentItem({
graphicType: "POLYLINE",
graphicData: longAxisGraphicData,
use3DSpatialCoordinates,
referencedSOPSequence: ReferencedSOPSequence,
referencedFrameOfReferenceUID: ReferencedFrameOfReferenceUID
}).contentItem();

const shortAxisContentSequence = new Tid320ContentItem({
graphicType: "POLYLINE",
graphicData: shortAxisGraphicData,
use3DSpatialCoordinates,
referencedSOPSequence: ReferencedSOPSequence,
referencedFrameOfReferenceUID: ReferencedFrameOfReferenceUID
}).contentItem();

return this.getMeasurement([
{
RelationshipType: "CONTAINS",
Expand All @@ -36,22 +53,7 @@ export default class Bidirectional extends TID300Measurement {
MeasurementUnitsCodeSequence: unit2CodingValue(unit),
NumericValue: longAxisLength
},
ContentSequence: {
RelationshipType: "INFERRED FROM",
ValueType: use3DSpatialCoordinates ? "SCOORD3D" : "SCOORD",
GraphicType: "POLYLINE",
GraphicData: longAxisGraphicData,
ReferencedFrameOfReferenceUID: use3DSpatialCoordinates
? ReferencedFrameOfReferenceUID
: undefined,
ContentSequence: use3DSpatialCoordinates
? undefined
: {
RelationshipType: "SELECTED FROM",
ValueType: "IMAGE",
ReferencedSOPSequence
}
}
ContentSequence: longAxisContentSequence
},
{
RelationshipType: "CONTAINS",
Expand All @@ -65,22 +67,7 @@ export default class Bidirectional extends TID300Measurement {
MeasurementUnitsCodeSequence: unit2CodingValue(unit),
NumericValue: shortAxisLength
},
ContentSequence: {
RelationshipType: "INFERRED FROM",
ValueType: use3DSpatialCoordinates ? "SCOORD3D" : "SCOORD",
GraphicType: "POLYLINE",
GraphicData: shortAxisGraphicData,
ReferencedFrameOfReferenceUID: use3DSpatialCoordinates
? ReferencedFrameOfReferenceUID
: undefined,
ContentSequence: use3DSpatialCoordinates
? undefined
: {
RelationshipType: "SELECTED FROM",
ValueType: "IMAGE",
ReferencedSOPSequence
}
}
ContentSequence: shortAxisContentSequence
}
]);
}
Expand Down
26 changes: 10 additions & 16 deletions src/utilities/TID300/Calibration.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import TID300Measurement from "./TID300Measurement.js";
import unit2CodingValue from "./unit2CodingValue.js";
import Tid320ContentItem from "./Tid320ContentItem.js";

export default class Calibration extends TID300Measurement {
contentItem() {
Expand All @@ -18,6 +19,14 @@ export default class Calibration extends TID300Measurement {
use3DSpatialCoordinates
});

const graphicContentSequence = new Tid320ContentItem({
graphicType: "POLYLINE",
graphicData: GraphicData,
use3DSpatialCoordinates,
referencedSOPSequence: ReferencedSOPSequence,
referencedFrameOfReferenceUID: ReferencedFrameOfReferenceUID
}).contentItem();

return this.getMeasurement([
{
RelationshipType: "CONTAINS",
Expand All @@ -31,22 +40,7 @@ export default class Calibration extends TID300Measurement {
MeasurementUnitsCodeSequence: unit2CodingValue(unit),
NumericValue: distance
},
ContentSequence: {
RelationshipType: "INFERRED FROM",
ValueType: use3DSpatialCoordinates ? "SCOORD3D" : "SCOORD",
GraphicType: "POLYLINE",
GraphicData,
ReferencedFrameOfReferenceUID: use3DSpatialCoordinates
? ReferencedFrameOfReferenceUID
: undefined,
ContentSequence: use3DSpatialCoordinates
? undefined
: {
RelationshipType: "SELECTED FROM",
ValueType: "IMAGE",
ReferencedSOPSequence
}
}
ContentSequence: graphicContentSequence
}
]);
}
Expand Down
108 changes: 60 additions & 48 deletions src/utilities/TID300/Circle.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import TID300Measurement from "./TID300Measurement.js";
import unit2CodingValue from "./unit2CodingValue.js";
import Tid320ContentItem from "./Tid320ContentItem.js";
import MeasurementBuilder from "../MeasurementBuilder.js";

export default class Circle extends TID300Measurement {
contentItem() {
Expand All @@ -11,7 +13,15 @@ export default class Circle extends TID300Measurement {
area,
areaUnit = "mm2",
unit = "mm",
ReferencedFrameOfReferenceUID
max,
min,
mean,
stdDev,
radiusUnit,
modalityUnit,
ReferencedFrameOfReferenceUID,
radius,
annotationIndex
} = this.props;

// Combine all lengths to save the perimeter
Expand All @@ -23,65 +33,67 @@ export default class Circle extends TID300Measurement {
use3DSpatialCoordinates
});

// TODO: Add Mean and STDev value of (modality?) pixels
const measurementConfigs = [
{
value: area,
unit: areaUnit,
builder: MeasurementBuilder.createAreaMeasurement
},
{
value: radius,
unit: radiusUnit,
builder: MeasurementBuilder.createRadiusMeasurement
},
{
value: max,
unit: modalityUnit,
builder: MeasurementBuilder.createMaxMeasurement
},
{
value: min,
unit: modalityUnit,
builder: MeasurementBuilder.createMinMeasurement
},
{
value: mean,
unit: modalityUnit,
builder: MeasurementBuilder.createMeanMeasurement
},
{
value: stdDev,
unit: modalityUnit,
builder: MeasurementBuilder.createStdDevMeasurement
}
];

return this.getMeasurement([
const measurements = [
{
RelationshipType: "CONTAINS",
ValueType: "NUM",
ConceptNameCodeSequence: {
CodeValue: "G-A197",
CodingSchemeDesignator: "SRT",
CodeMeaning: "Perimeter" // TODO: Look this up from a Code Meaning dictionary
CodeMeaning: "Perimeter"
},
MeasuredValueSequence: {
MeasurementUnitsCodeSequence: unit2CodingValue(unit),
NumericValue: perimeter
},
ContentSequence: {
RelationshipType: "INFERRED FROM",
ValueType: use3DSpatialCoordinates ? "SCOORD3D" : "SCOORD",
GraphicType: "CIRCLE",
GraphicData,
ReferencedFrameOfReferenceUID: use3DSpatialCoordinates
? ReferencedFrameOfReferenceUID
: undefined,
ContentSequence: use3DSpatialCoordinates
? undefined
: {
RelationshipType: "SELECTED FROM",
ValueType: "IMAGE",
ReferencedSOPSequence
}
}
ContentSequence: new Tid320ContentItem({
graphicType: "CIRCLE",
graphicData: GraphicData,
use3DSpatialCoordinates,
referencedSOPSequence: ReferencedSOPSequence,
referencedFrameOfReferenceUID: ReferencedFrameOfReferenceUID
}).contentItem()
},
{
// TODO: This feels weird to repeat the GraphicData
RelationshipType: "CONTAINS",
ValueType: "NUM",
ConceptNameCodeSequence: {
CodeValue: "G-A166",
CodingSchemeDesignator: "SRT",
CodeMeaning: "Area" // TODO: Look this up from a Code Meaning dictionary
},
MeasuredValueSequence: {
MeasurementUnitsCodeSequence: unit2CodingValue(areaUnit),
NumericValue: area
},
ContentSequence: {
RelationshipType: "INFERRED FROM",
ValueType: use3DSpatialCoordinates ? "SCOORD3D" : "SCOORD",
GraphicType: "CIRCLE",
GraphicData,
ContentSequence: use3DSpatialCoordinates
? undefined
: {
RelationshipType: "SELECTED FROM",
ValueType: "IMAGE",
ReferencedSOPSequence
}
}
}
]);
...measurementConfigs
.filter(config => config.value !== undefined)
.map(config =>
config.builder(config.value, config.unit, annotationIndex)
)
];

return this.getMeasurement(measurements);
}
}
Loading
Loading