Skip to content

Commit

Permalink
fix: Angle and CobbAngle tool: set default 1 for rowPixelSpacing and …
Browse files Browse the repository at this point in the history
…columnPixelSpacing (#1229)

* Set default 1 for rowPixelSpacing and columnPixelSpacing values at the angle and cobbangle tool

* Updated line length in angle tool

* Revert "Updated line length in angle tool"

This reverts commit 68cfbe2.

* Updated updateCachedStats method length

* Revert "Updated updateCachedStats method length"

This reverts commit a1a0421.

* Angle tool - updateCachedStats method refactoring.

* Angle Tool unit tests.

Co-authored-by: Amina <[email protected]>
Co-authored-by: Danny Brown <[email protected]>
  • Loading branch information
3 people authored May 29, 2020
1 parent 3ff4f87 commit d16ecd4
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 20 deletions.
28 changes: 12 additions & 16 deletions src/tools/annotation/AngleTool.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,22 +112,9 @@ export default class AngleTool extends BaseAnnotationTool {
}

updateCachedStats(image, element, data) {
const { rowPixelSpacing, colPixelSpacing } = getPixelSpacing(image);

const sideA = {
x: (data.handles.middle.x - data.handles.start.x) * colPixelSpacing,
y: (data.handles.middle.y - data.handles.start.y) * rowPixelSpacing,
};

const sideB = {
x: (data.handles.end.x - data.handles.middle.x) * colPixelSpacing,
y: (data.handles.end.y - data.handles.middle.y) * rowPixelSpacing,
};

const sideC = {
x: (data.handles.end.x - data.handles.start.x) * colPixelSpacing,
y: (data.handles.end.y - data.handles.start.y) * rowPixelSpacing,
};
const sideA = getSide(image, data.handles.middle, data.handles.start);
const sideB = getSide(image, data.handles.end, data.handles.middle);
const sideC = getSide(image, data.handles.end, data.handles.middle);

This comment has been minimized.

Copy link
@sbourouis

sbourouis Jun 22, 2020

Contributor

sideC is incorrect. Should be

const sideC = getSide(image, data.handles.end, data.handles.start);

const sideALength = length(sideA);
const sideBLength = length(sideB);
Expand Down Expand Up @@ -360,3 +347,12 @@ export default class AngleTool extends BaseAnnotationTool {
function length(vector) {
return Math.sqrt(Math.pow(vector.x, 2) + Math.pow(vector.y, 2));
}

function getSide(image, handleEnd, handleStart) {
const { rowPixelSpacing, colPixelSpacing } = getPixelSpacing(image);

return {
x: (handleEnd.x - handleStart.x) * (colPixelSpacing || 1),
y: (handleEnd.y - handleStart.y) * (rowPixelSpacing || 1),
};
}
173 changes: 173 additions & 0 deletions src/tools/annotation/AngleTool.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import AngleTool from './AngleTool.js';
import { getToolState } from './../../stateManagement/toolState.js';

jest.mock('./../../stateManagement/toolState.js', () => ({
getToolState: jest.fn(),
}));

jest.mock('./../../importInternal.js', () => ({
default: jest.fn(),
}));

jest.mock('./../../externalModules.js', () => ({
cornerstone: {
metaData: {
get: jest.fn(),
},
},
}));

const goodMouseEventData = {
currentPoints: {
image: {
x: 0,
y: 0,
},
},
};

const image = {
rowPixelSpacing: 0.8984375,
columnPixelSpacing: 0.8984375,
};

describe('AngleTool.js', () => {
describe('default values', () => {
it('has a default name of "Angle"', () => {
const defaultName = 'Angle';
const instantiatedTool = new AngleTool();

expect(instantiatedTool.name).toEqual(defaultName);
});

it('can be created with a custom tool name', () => {
const customToolName = { name: 'customToolName' };
const instantiatedTool = new AngleTool(customToolName);

expect(instantiatedTool.name).toEqual(customToolName.name);
});
});

describe('createNewMeasurement', () => {
it('returns an angle tool object', () => {
const instantiatedTool = new AngleTool('Angle');

const toolMeasurement = instantiatedTool.createNewMeasurement(
goodMouseEventData
);

expect(typeof toolMeasurement).toBe(typeof {});
});

it("returns a measurement with a start, middle and end handle at the eventData's x and y", () => {
const instantiatedTool = new AngleTool('toolName');

const toolMeasurement = instantiatedTool.createNewMeasurement(
goodMouseEventData
);
const startHandle = {
x: toolMeasurement.handles.start.x,
y: toolMeasurement.handles.start.y,
};
const middleHandle = {
x: toolMeasurement.handles.middle.x,
y: toolMeasurement.handles.middle.y,
};
const endHandle = {
x: toolMeasurement.handles.end.x,
y: toolMeasurement.handles.end.y,
};

expect(startHandle.x).toBe(goodMouseEventData.currentPoints.image.x);
expect(startHandle.y).toBe(goodMouseEventData.currentPoints.image.y);
expect(middleHandle.x).toBe(goodMouseEventData.currentPoints.image.x);
expect(middleHandle.y).toBe(goodMouseEventData.currentPoints.image.y);
expect(endHandle.x).toBe(goodMouseEventData.currentPoints.image.x);
expect(endHandle.y).toBe(goodMouseEventData.currentPoints.image.y);
});

it('returns a measurement with a textBox handle', () => {
const instantiatedTool = new AngleTool('toolName');

const toolMeasurement = instantiatedTool.createNewMeasurement(
goodMouseEventData
);

expect(typeof toolMeasurement.handles.textBox).toBe(typeof {});
});
});

describe('pointNearTool', () => {
let element, coords;

beforeEach(() => {
element = jest.fn();
coords = jest.fn();
});

it('returns false when measurement data is not visible', () => {
const instantiatedTool = new AngleTool('AngleTool');
const notVisibleMeasurementData = {
visible: false,
};

const isPointNearTool = instantiatedTool.pointNearTool(
element,
notVisibleMeasurementData,
coords
);

expect(isPointNearTool).toBe(false);
});
});

describe('updateCachedStats', () => {
let element;

beforeEach(() => {
element = jest.fn();
});

it('should calculate and update annotation value', () => {
const instantiatedTool = new AngleTool('AngleTool');

const data = {
handles: {
start: {
x: 166,
y: 90,
},
middle: {
x: 120,
y: 113,
},
end: {
x: 145,
y: 143,
},
},
};

instantiatedTool.updateCachedStats(image, element, data);
expect(data.rAngle).toBe(48.82);
expect(data.invalidated).toBe(false);
});
});

describe('renderToolData', () => {
it('returns undefined when no toolData exists for the tool', () => {
const instantiatedTool = new AngleTool('AngleTool');
const mockEvent = {
detail: {
enabledElement: undefined,
},
};

getToolState.mockReturnValueOnce(undefined);

const renderResult = instantiatedTool.renderToolData(mockEvent);

expect(renderResult).toBe(undefined);
});
});
});
8 changes: 4 additions & 4 deletions src/tools/annotation/CobbAngleTool.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,16 +133,16 @@ export default class CobbAngleTool extends BaseAnnotationTool {

const dx1 =
(Math.ceil(data.handles.start.x) - Math.ceil(data.handles.end.x)) *
colPixelSpacing;
(colPixelSpacing || 1);
const dy1 =
(Math.ceil(data.handles.start.y) - Math.ceil(data.handles.end.y)) *
rowPixelSpacing;
(rowPixelSpacing || 1);
const dx2 =
(Math.ceil(data.handles.start2.x) - Math.ceil(data.handles.end2.x)) *
colPixelSpacing;
(colPixelSpacing || 1);
const dy2 =
(Math.ceil(data.handles.start2.y) - Math.ceil(data.handles.end2.y)) *
rowPixelSpacing;
(rowPixelSpacing || 1);

let angle = Math.acos(
Math.abs(
Expand Down

0 comments on commit d16ecd4

Please sign in to comment.