Measurements

class core.Measurements

Bases: matlab.mixin.Copyable

MEASUREMENTS - Container for measurement data and visualization in MIB3.

This class stores all measurement data for a dataset and provides methods for adding, removing, rendering, and coordinate-transforming measurements. It is data-only: it never references a controller, view, or axes-creation logic. All interactive UX (click acquisition, dialogs, tool activation) is handled by controllers.MibMeasureToolController (future).

Supported measurement types:

  • 'Point' - single labelled point

  • 'Distance (linear)' - straight-line distance between two points

  • 'Distance (polyline)' - cumulative arc-length of a polyline

  • 'Angle' - angle formed by three points (vertex = point 2)

  • 'Circle (R)' - circle fit to N points; result is radius

  • 'Caliper' - oriented bounding-box width measurement

Data structure - each element of obj.Data struct array contains:

  • .n - [double] 1-based index (auto-renumbered on insert/delete)

  • .type - [char] measurement type string (see list above)

  • .value - [double] numeric result in physical units

  • .X - [double vector] data-space pixel X coordinates

  • .Y - [double vector] data-space pixel Y coordinates

  • .Z - [double] Z slice index when measurement was made

  • .T - [double] time-point index when measurement was made

  • .orientation - [double] 1 = zx, 2 = zy, 3 = yx (MIB3 values)

  • .spline - [struct | []] ppval data for 'Distance (polyline)'

  • .circ - [struct | []] {xc, yc, R} for 'Circle (R)'

  • .intensity - [double vector] mean intensity per colour channel

  • .profile - [double matrix] [position; intensity_ch1; ...]

  • .integrateWidth - [double | []] integration half-width for 'Distance (linear)'

  • .info - [char] user annotation / label text

  • .colCh - [double] colour channel used when measurement was made

Interactive UX (drawing, dialogs, export) belongs to controllers.MibMeasureToolController.

Constructor Summary
Measurements(mibDataset)

MEASUREMENTS - Constructor for the Measurements class.

Syntax:
obj = core.Measurements(mibDataset)

Creates a new instance with default options and empty data. Typically instantiated inside core.MibDataset.initialize and stored as obj.measurements.

Input Arguments:
  • mibDataset - (optional) handle to core.MibDataset (the parent dataset that owns this measurement collection). When omitted the class still works but methods that need image dimensions require explicit arguments.

Output Arguments:
Usage:

Example 1

measurements = core.Measurements(obj);% call from MibDataset.initialize

Example 2

measurements = core.Measurements();% standalone, no dataset reference
Property Summary
Data
Options
fixZ
mibDataset
typeToShow
Method Summary
addMeasurementsToPlot(axesHandle, mode, orientation, convertFcn, selectedIdx)

#ok<INUSL> ADDMEASUREMENTSTOPLOT - Render measurement overlays on the given axes.

Syntax:
obj.addMeasurementsToPlot(axesHandle, mode, orientation, convertFcn)
obj.addMeasurementsToPlot(axesHandle, mode, orientation, convertFcn, selectedIdx)

Plots measurements visible on the current Z slice and time point. Coordinate conversion is injected via convertFcn so the class never calls mibModel directly.

Input Arguments:
  • axesHandle - handle to the target axes.

  • mode - [char] rendering mode passed by the caller: 'shown' for the standard block-mode viewport, 'full' for the full-resolution pan coordinate system. Stored for future use; the actual coordinate mapping is performed by convertFcn.

  • orientation - [double] current orientation (3 = yx, 1 = zx, 2 = zy).

  • convertFcn - [function_handle] @(X,Y) ... that converts data coordinates to axes coordinates: [Xscreen, Yscreen] = convertFcn(Xdata, Ydata)

  • selectedIdx - (optional) [double] 0 = all visible; >0 = only that index. Default 0.

Output Arguments:

Usage:

Example 1

convertFcn = @(x,y) obj.mibModel.convertDataToMouseCoordinates(x, y, 'shown');
ds.measurements.addMeasurementsToPlot(ax, 'shown', ds.orientation, convertFcn, 0);
clearContents()

CLEARCONTENTS - Reset all class properties to default values.

Syntax:
obj.clearContents()

Calls setDefaultOptions(), clearData(), and resets fixZ to false.

Input Arguments:

Output Arguments:

Usage:

Example 1

obj.mibModel.I{obj.mibModel.id}.measurements.clearContents();

Example 2

clearContents(obj);% call within the class
clearData()

CLEARDATA - Remove all stored measurements, resetting Data to an empty struct.

Syntax:
obj.clearData()

Resets obj.Data to an empty single-element struct with all required field names initialised to []. Also resets typeToShow to 'All' if it is not already set.

Input Arguments:

Output Arguments:

Usage:

Example 1

obj.mibModel.I{obj.mibModel.id}.measurements.clearData();

Example 2

clearData(obj);% call within the class
static computeAngle(X, Y, pixSize, orientation)

COMPUTEANGLE - Compute the angle in degrees formed by three points.

Syntax:
angleValue = core.Measurements.computeAngle(X, Y, pixSize, orientation)

The second point (X(2), Y(2)) is the vertex of the angle. Physical pixel size is applied per orientation before computing the angle so that non-isotropic datasets give correct results.

Input Arguments:
  • X - [double(1×3)] X coordinates of the three points.

  • Y - [double(1×3)] Y coordinates of the three points.

  • pixSize - [struct] pixel/voxel size with fields .x, .y, .z.

  • orientation - (optional) [double] 1 = zx, 2 = zy, 3 = yx. Default 3.

Output Arguments:
  • angleValue - [double] angle at the vertex in degrees.

Usage:

Example 1

pixSize.x = 0.1; pixSize.y = 0.1; pixSize.z = 0.3;
angleValue = core.Measurements.computeAngle([10 20 30], [10 20 10], pixSize, 3);
static computeCircleFit(x, y)

COMPUTECIRCLEFIT - Least-squares circle fitting to a set of 2-D points.

Syntax:
circ = core.Measurements.computeCircleFit(x, y)

Adapted from the MIB2 circlefit function.

Input Arguments:
  • x - [double vector] X coordinates of the input points.

  • y - [double vector] Y coordinates of the input points.

Output Arguments:
  • circ - [struct] with fields:

    • .xc - X coordinate of the fitted circle centre

    • .yc - Y coordinate of the fitted circle centre

    • .R - radius of the fitted circle

Usage:

Example 1

circ = core.Measurements.computeCircleFit([0 1 0 -1], [1 0 -1 0]);
% circ.xc ≈ 0, circ.yc ≈ 0, circ.R ≈ 1
static computeDistance(X, Y, pixSize, orientation)

COMPUTEDISTANCE - Compute the Euclidean distance between two points in physical units.

Syntax:
distanceValue = core.Measurements.computeDistance(X, Y, pixSize, orientation)
Input Arguments:
  • X - [double(1×2)] X coordinates of the two endpoints.

  • Y - [double(1×2)] Y coordinates of the two endpoints.

  • pixSize - [struct] pixel/voxel size with fields .x, .y, .z.

  • orientation - (optional) [double] 1 = zx, 2 = zy, 3 = yx. Default 3.

Output Arguments:
  • distanceValue - [double] Euclidean distance in physical units.

Usage:

Example 1

pixSize.x = 0.1; pixSize.y = 0.1; pixSize.z = 0.3;
distanceValue = core.Measurements.computeDistance([10 20], [10 30], pixSize, 3);
static computeKymograph(imageStack, X, Y)

COMPUTEKYMOGRAPH - Build a kymograph from a line measurement over a Z/T stack.

Syntax:
kymograph = core.Measurements.computeKymograph(imageStack, X, Y)
Input Arguments:
  • imageStack - [H × W × C × nSlices] uint or double array (not a cell; use imageStackCell{1} and permute from getData4D output).

  • X - [double(1×2)] line endpoint X coords (pixel space).

  • Y - [double(1×2)] line endpoint Y coords (pixel space).

Output Arguments:
  • kymograph - [nSlices × nPoints × C] array of the same class as imageStack(:,:,:,1), where rows = slices/frames and columns = positions along the line.

Usage:

Example 1

stack = obj.mibModel.getData4D('image', [], [], options);
kymo  = core.Measurements.computeKymograph(stack, [10 200], [50 50]);
static computeProfile(image2D, X, Y, ~, ~)

COMPUTEPROFILE - Compute an intensity profile along a polyline path.

Syntax:
profileData = core.Measurements.computeProfile(image2D, X, Y, pixSize, orientation)

The caller fetches the 2-D image slice via getData2D with block-mode off and passes it here. The result is a matrix suitable for line-profile plots.

Input Arguments:
  • image2D - [H × W × C double or uint] intensity image.

  • X - [double vector] polyline vertex X coords (data space).

  • Y - [double vector] polyline vertex Y coords (data space).

  • pixSize - [struct] pixel size (currently unused but reserved for physical-unit arc lengths in future).

  • orientation - (optional) [double] reserved; default 3.

Output Arguments:
  • profileData - [double matrix] rows = [position; ch1; ch2; …] where position is cumulative arc length in pixels and each chN row contains the interpolated intensity for colour channel N.

Usage:

Example 1

img = obj.mibModel.getData2D('image', [], [], [], options);
profileData = core.Measurements.computeProfile(img, X, Y, pixSize);
crop(cropF)

CROP - Recalculate measurement positions after image crop.

Syntax:
obj.crop(cropF)

Shifts all stored coordinates by the crop origin depending on the measurement’s orientation. Also shifts circle and spline coordinates if present.

Input Arguments:
  • cropF - [numeric vector] [x1, y1, dx, dy, z1, dz]:

    • cropF(1) - starting X coordinate (1-based)

    • cropF(2) - starting Y coordinate (1-based)

    • cropF(3) - width of crop region

    • cropF(4) - height of crop region

    • cropF(5) - starting Z slice (1-based)

    • cropF(6) - number of Z slices

Output Arguments:

Usage:

Example 1

obj.mibModel.I{obj.mibModel.id}.measurements.crop([100, 50, 200, 200, 1, 10]);

Example 2

crop(obj, [1, 1, 512, 512, 5, 20]);% call within the class
findIndexByLabel(queryStr)

FINDINDEXBYLABEL - Find measurements whose info field matches a query string.

Syntax:
indices = obj.findIndexByLabel(queryStr)

Searches obj.Data for elements whose .info field equals queryStr.

Input Arguments:
  • queryStr - [char | string] label text to search for.

Output Arguments:
  • indices - [numeric vector] indices of matching entries. Empty if no match found.

Usage:

Example 1

indices = obj.mibModel.I{obj.mibModel.id}.measurements.findIndexByLabel('nucleus');

Example 2

indices = findIndexByLabel(obj, 'dist1');% call within the class
getNumberOfMeasurements()

GETNUMBEROFMEASUREMENTS - Return the total number of stored measurements.

Syntax:
measurementCount = obj.getNumberOfMeasurements()

Returns 0 when the Data struct array is in its empty initial state (i.e. obj.Data(1).n is empty).

Input Arguments:

Output Arguments:
  • measurementCount - [double] number of stored measurements.

Usage:

Example 1

measurementCount = obj.mibModel.I{obj.mibModel.id}.measurements.getNumberOfMeasurements();
removeMeasurement(index)

REMOVEMEASUREMENT - Remove one or more measurements from the Data array.

Syntax:
obj.removeMeasurement(index)

When index is 0, empty, or omitted all measurements are removed (calls clearData). When the removal would leave the array empty, clearData is also called. Otherwise the element(s) are deleted and .n is renumbered.

No confirmation dialog is shown - caller is responsible for prompting the user before invoking this method.

Input Arguments:
  • index - (optional) [double] index of the measurement to remove. Use 0 or omit to remove all.

Output Arguments:

Usage:

Example 1

obj.mibModel.I{obj.mibModel.id}.measurements.removeMeasurement(3);% remove 3rd

Example 2

obj.mibModel.I{obj.mibModel.id}.measurements.removeMeasurement(0);% remove all

Example 3

obj.mibModel.I{obj.mibModel.id}.measurements.removeMeasurement();% remove all
resample(resampledRatio)

RESAMPLE - Recalculate measurement positions after image resampling.

Syntax:
obj.resample(resampledRatio)

Scales X, Y coordinates of every stored measurement by the appropriate ratio depending on the measurement’s orientation. Also scales circle centre/radius and spline coordinates if present.

Input Arguments:
  • resampledRatio - [numeric vector] [ratioW, ratioH, ratioZ] ratio of new/old dimensions. For example [0.5, 0.5, 1] bins XY by 2.

Output Arguments:

Usage:

Example 1

obj.mibModel.I{obj.mibModel.id}.measurements.resample([0.5, 0.5, 1]);

Example 2

resample(obj, [2, 2, 2]);% call within the class; double all dimensions
setDefaultOptions()

SETDEFAULTOPTIONS - Set all Options fields to their default values.

Syntax:
obj.setDefaultOptions()

Input Arguments:

Output Arguments:

Usage:

Example 1

obj.mibModel.I{obj.mibModel.id}.measurements.setDefaultOptions();

Example 2

setDefaultOptions(obj);% call within the class
storeMeasurement(newData, index)

STOREMEASUREMENT - Add or insert a pre-computed measurement struct.

Syntax:
obj.storeMeasurement(newData)
obj.storeMeasurement(newData, index)

If index is less than or equal to the current number of measurements, the new entry is inserted at that position (existing entries shift forward). Otherwise the entry is appended. After any insert all .n fields are renumbered.

Input Arguments:
  • newData - [struct] single measurement struct whose fields match those of obj.Data.

  • index - (optional) [double] position at which to store the measurement. Default = append after the last entry.

Output Arguments:

Usage:

Example 1

obj.mibModel.I{obj.mibModel.id}.measurements.storeMeasurement(newData);% append

Example 2

obj.mibModel.I{obj.mibModel.id}.measurements.storeMeasurement(newData, 3);% insert at position 3
static swapZXAxes(Data)

SWAPZXAXES - Swap the horizontal/vertical axes of measurements made in the ZX orientation.

Syntax:
Data = core.Measurements.swapZXAxes(Data)

ZX slices are [z, x] (rows = Z, columns = X, see core.MibImage.getData()), so in memory a ZX measurement keeps dataset X in .X and Z in .Y. MIB2 and earlier MIB3 versions showed ZX transposed (rows = X, columns = Z), and .measure files store ZX measurements in that legacy frame. This conversion is its own inverse: it is applied to the data read from a .measure file (controllers.MeasureTool.loadMeasurements) and to the data written to one (controllers.MeasureTool.saveMeasurements), so files stay compatible in both directions. Only entries with .orientation == 1 change: .X/.Y, .circ.xc/.circ.yc and .spline.x/.spline.y are swapped.

Input Arguments:
  • Data - [struct array] measurement data, see the class header

Output Arguments:
  • Data - [struct array] the same measurements, ZX entries swapped

Usage:

Example 1 - load a .measure file:

loadedStruct = load(filename, '-mat');
Data = core.Measurements.swapZXAxes(loadedStruct.Data);
updateOptions(parentFigure)

UPDATEOPTIONS - Show an interactive dialog to update display Options.

Syntax:
obj.updateOptions(parentFigure)

Opens utils.dlgs.inputUniversalDlg with the current option values as defaults. If the user cancels, no changes are made.

Input Arguments:
  • parentFigure - handle to the parent window used for dialog centering. Pass [] for automatic placement.

Output Arguments:

Usage:

Example 1

obj.mibModel.I{obj.mibModel.id}.measurements.updateOptions(obj.mibController.view.gui);

Example 2

obj.mibModel.I{obj.mibModel.id}.measurements.updateOptions([]);