larmor.viewer#

The viewer, lar bv, and opening it from Python.

MAX_STREAMLINES

Tractograms with more streamlines are reduced to a random subset when read.

Basis

The SH bases an FOD's coefficients can be in; the file does not say which.

CameraPreset

The standard positions of the 3D camera.

Category

A kind of item: a key of the registry.

Colormap

The colormaps an image can be shown with.

Colouring

How a tractogram's streamlines are coloured.

Convention

How the 2D views show left and right.

FodInspector

Draws one FOD item's glyph at the cursor, centred, large and in high detail.

GlyphScaling

What an FOD glyph's size is relative to.

Item

One loaded file or object.

ItemId

LoadAs

What one variable is loaded as, in a manual import.

MatlabPreset

What to load from a MATLAB file.

OptionError

A value an option does not accept; the message says why, for the user.

OptionName

The options of every item type; each is a field of an options class.

PortInUseError

The MCP server's port is taken by another program.

Readout

The cursor's position and, with a main volume, its voxel and value there.

RegionRole

What a region does to the streamlines of a tractogram.

SessionError

A file that is not a session this version can read; the message says why.

SessionReport

What opening a session did.

TractStyle

How the 3D view draws a tractogram's streamlines.

ViewKind

One of the four views.

Viewer

The viewer's state and the actions that change it.

ViewerUnavailableError

The viewer cannot start on this machine.

view

Opens the viewer's window on files or objects, given by category.

wait

Waits until the files given to view or opened in the window are loaded.

larmor.viewer.MAX_STREAMLINES = 1000000#

Tractograms with more streamlines are reduced to a random subset when read.

class larmor.viewer.Basis#

The SH bases an FOD’s coefficients can be in; the file does not say which.

TOURNIER = 'tournier'#
DESCOTEAUX = 'descoteaux'#
LEEMANS = 'leemans'#
class larmor.viewer.CameraPreset#

The standard positions of the 3D camera.

AXIAL = 'axial'#
CORONAL = 'coronal'#
SAGITTAL = 'sagittal'#
class larmor.viewer.Category#

A kind of item: a key of the registry.

VOLUMES = 'volumes'#
OVERLAYS = 'overlays'#
TRACTOGRAMS = 'tractograms'#
FODS = 'fods'#
PEAKS = 'peaks'#
SURFACES = 'surfaces'#
class larmor.viewer.Colormap#

The colormaps an image can be shown with.

GRAY = 'gray'#
HOT = 'hot'#
VIRIDIS = 'viridis'#
INFERNO = 'inferno'#
MAGMA = 'magma'#
PLASMA = 'plasma'#
CIVIDIS = 'cividis'#
JET = 'jet'#
BONE = 'bone'#
COOL = 'cool'#
GRAY_R = 'gray_r'#
BLUE_RED = 'blue_dark_red'#
class larmor.viewer.Colouring#

How a tractogram’s streamlines are coloured.

DIRECTION = 'direction'#
SINGLE = 'single_colour'#
PER_TRACTOGRAM = 'per_tractogram'#
VALUES = 'by_value'#
class larmor.viewer.Convention#

How the 2D views show left and right.

RAS = 'RAS'#
LAS = 'LAS'#
class larmor.viewer.FodInspector(viewer, item_id, canvas=None, removed=None)#

Draws one FOD item’s glyph at the cursor, centred, large and in high detail.

It follows the cursor and the item’s basis and colouring, and makes the glyph again only when the voxel or the basis changes. The threshold, anisotropy, scale, scaling, detail, opacity and visibility of the slices do not apply: the voxel’s FOD is always shown, scaled to the same size. The camera is the inspector’s own, not the model’s: it turns and zooms about the glyph. Paused, it only notes that the scene changed, and catches up when it resumes. Without a canvas it draws off screen.

on_event(event)#

Follows the cursor, the item’s basis and colouring, and its removal.

Parameters:

event (Event) – The scene event.

pause()#

Stops making the glyph and drawing until it resumes.

resume()#

Colours the glyph and makes it again if the scene changed meanwhile.

close()#

Stops following the scene; frees the canvas if it made it.

rotate(right, up)#

Turns the glyph by degrees on the screen, as the 3D view turns its scene.

Parameters:
  • right (float) – Degrees to turn the glyph to the right.

  • up (float) – Degrees to turn it upwards.

zoom(factor)#

Zooms by a factor, within the views’ zoom range.

Parameters:

factor (float) – The factor to multiply the zoom by.

reset_camera()#

Looks at the glyph as at first: as the 3D view’s reset, at zoom 1.

draw()#

Renders the glyph and the axes, then the text.

render()#

Draws off screen; the image, (height, width, 3) uint8 RGB.

Returns:

The image.

Return type:

ndarray

save(path)#

Draws off screen and writes the image to a file.

Parameters:

path (str | Path) – The image file to write.

Returns:

The path written.

Return type:

Path

class larmor.viewer.GlyphScaling#

What an FOD glyph’s size is relative to.

PER_VOXEL = 'per_voxel'#
IMAGE = 'whole_image'#
class larmor.viewer.Item(id, category, name, source, data, options, value_range=None, part=None, registration=None)#

One loaded file or object.

id#

The item’s id in its viewer.

Type:

larmor.viewer.model.item.ItemId

category#

Which kind of item it is.

Type:

larmor.viewer.model.item.Category

name#

The file’s name, or the name given from Python.

Type:

str

source#

The file, or None for an object given from Python.

Type:

pathlib.Path | None

data#

The Volume, Tractogram or surface data it shows.

Type:

object

options#

The item’s options.

Type:

larmor.viewer.model.options.ItemOptions

value_range#

The data’s minimum and maximum in scaled units for an image, the range of all a surface’s values per vertex; None for the others.

Type:

tuple[float, float] | None

part#

What the item was read from inside a MATLAB file; None for any other.

Type:

MatlabPart | None

registration#

The registration the item was brought through when loaded.

Type:

Registration | None

property volume_count: int | None#

The numbers of data on the 4-th dimension, if available.

type larmor.viewer.ItemId = int#
class larmor.viewer.LoadAs#

What one variable is loaded as, in a manual import.

NOTHING = 'nothing'#
VOLUME = 'volume'#
OVERLAY = 'overlay'#
FODS = 'fods'#
PEAKS = 'peaks'#
TRACTOGRAM = 'tractogram'#
POINT_VALUES = 'point_values'#
SURFACE = 'surface'#
class larmor.viewer.MatlabPreset#

What to load from a MATLAB file.

TENSOR_FIT = 'tensor_fit'#
FOD_FIT = 'fod_fit'#
TRACTOGRAPHY = 'tractography'#
MANUAL = 'manual'#
exception larmor.viewer.OptionError#

A value an option does not accept; the message says why, for the user.

class larmor.viewer.OptionName#

The options of every item type; each is a field of an options class.

VISIBLE = 'visible'#
OPACITY_2D = 'opacity_2d'#
OPACITY_3D = 'opacity_3d'#
COLORMAP = 'colormap'#
INTERPOLATE = 'interpolate'#
MINIMUM = 'minimum'#
MAXIMUM = 'maximum'#
THRESHOLD = 'threshold'#
LABELS = 'labels'#
LOOKUP_TABLE = 'lookup_table'#
VOLUME_INDEX = 'volume_index'#
COLOUR_BAR = 'colour_bar'#
SLICES_3D = 'slices_3d'#
SURFACE_3D = 'surface_3d'#
COLOURING = 'colouring'#
COLOUR = 'colour'#
SUBSET = 'subset'#
POINTS = 'points'#
SLAB = 'slab'#
SLAB_THICKNESS = 'slab_thickness'#
BASIS = 'basis'#
SCALE = 'scale'#
SCALING = 'scaling'#
DETAIL = 'detail'#
ANISOTROPY = 'anisotropy'#
AMPLITUDE = 'amplitude'#
ASYMMETRIC_PEAKS = 'asymmetric_peaks'#
LINE_WIDTH = 'line_width'#
SURFACE_LABELS = 'surface_labels'#
DTI = 'dti'#
MODULATE = 'modulate'#
STYLE = 'style'#
TUBE_RADIUS = 'tube_radius'#
COLOUR_BY = 'colour_by'#
CUT_LINES = 'cut_lines'#
HIDE_MEDIAL_WALL = 'hide_medial_wall'#
SHOW_NORMALS = 'show_normals'#
NORMALS_COUNT = 'normals_count'#
NORMALS_LENGTH = 'normals_length'#
NORMALS_SPACING = 'normals_spacing'#
NORMALS_COLOURING = 'normals_colouring'#
NORMALS_COLOUR = 'normals_colour'#
VALUES_FILE = 'values_file'#
VALUES_VOLUME = 'values_volume'#
REGION_FILTER = 'region_filter'#
INCLUDE_MASKS = 'include_masks'#
EXCLUDE_MASKS = 'exclude_masks'#
INCLUDE_SPHERES = 'include_spheres'#
EXCLUDE_SPHERES = 'exclude_spheres'#
WITHIN_MASKS = 'within_masks'#
WITHIN_SPHERES = 'within_spheres'#
ENDS_ONLY = 'ends_only'#
exception larmor.viewer.PortInUseError#

The MCP server’s port is taken by another program.

class larmor.viewer.Readout(position, name=None, voxel=None, value=None)#

The cursor’s position and, with a main volume, its voxel and value there.

position#

The cursor in world coordinates, mm.

Type:

larmor.viewer.model.readout.Vec3

name#

The main volume’s name; None without one.

Type:

str | None

voxel#

The nearest voxel (with the volume index of a 4D image); None outside the grid.

Type:

tuple[int, …] | None

value#

The value there in scaled units; None outside the grid.

Type:

float | None

class larmor.viewer.RegionRole#

What a region does to the streamlines of a tractogram.

INCLUDE = 'include'#
EXCLUDE = 'exclude'#
WITHIN = 'within'#
exception larmor.viewer.SessionError#

A file that is not a session this version can read; the message says why.

class larmor.viewer.SessionReport(items=(), problems=())#

What opening a session did.

items#

The items opened, in Layers order.

Type:

tuple[larmor.viewer.model.item.Item, …]

problems#

The files that could not be opened and the options or view-state fields that were refused, one sentence each.

Type:

tuple[str, …]

class larmor.viewer.TractStyle#

How the 3D view draws a tractogram’s streamlines.

LINES = 'lines'#
TUBES = 'tubes'#
class larmor.viewer.ViewKind#

One of the four views.

AXIAL = 'axial'#
CORONAL = 'coronal'#
SAGITTAL = 'sagittal'#
THREE_D = '3d'#
class larmor.viewer.Viewer(scene=None)#

The viewer’s state and the actions that change it.

Every change to what the viewer shows goes through these methods, whether it comes from the window, from lar bv or from Python, so each behaviour exists once. The window and the drawing follow the scene’s events. A viewer needs no window: view opens one on it, and screenshot draws a view off screen.

Positions are world coordinates in mm, RAS+ (x towards the subject’s right, y anterior, z superior), as in the items’ affines. Categories, views and option names are enums: Category, ViewKind and OptionName.

Parameters:

scene (Scene | None) – The scene to act on; a new empty one if None.

scene#

The items and the view state; read it, change it only through the actions.

Example

>>> viewer = Viewer()
>>> t1 = viewer.load("t1.nii.gz", Category.VOLUMES)
>>> viewer.set(t1.id, OptionName.COLORMAP, Colormap.BONE)
>>> viewer.screenshot(ViewKind.AXIAL, "axial.png")
load(path, category, *, max_streamlines=1000000, transforms=None, reference=None, inverse=False, interpolation=None, format=None, warp_type=None, fsl_input_path=None, fsl_reference_path=None)#

Reads a file into a new item of category, as add adds it.

The file is read before the method returns. Volumes, overlays, FODs and peaks are NIfTI (.nii, .nii.gz) or MRtrix (.mif, .mif.gz, .mih) images; tractograms are TCK, TRK or VTK files; surfaces are GIfTI (.gii) or FreeSurfer surfaces (such as lh.white). For a FreeSurfer surface, lh.curv in its folder is read as its values “curv”, and ../label/lh.cortex.label as its cortex, when they exist.

Parameters:
  • path (str | Path) – The file to read.

  • category (Category) – Where the item goes: Category.VOLUMES, OVERLAYS (masks, maps, parcellations), TRACTOGRAMS, FODS, PEAKS (from lar peaks) or SURFACES.

  • max_streamlines (int | None) – A tractogram with more streamlines keeps a random subset of this size; the same file always gives the same subset. None keeps all. Ignored for images.

  • transforms (list[str] | None) – Bring the item into another space through a registration computed by ANTs, FSL or MRtrix3: its transform files, listed as antsApplyTransforms lists them (an affine, a warp, or a warp and the inverse warp its tool wrote as “warp,inverse_warp”). The files are those that resample an image into the reference space; tractograms and surfaces are brought into the same space. FODs cannot be brought through a registration. None loads the file as it is.

  • reference (str | Path | None) – With transforms: an image of the reference space, whose grid images are resampled onto (needed for images).

  • inverse (bool) – With transforms: go the other way, from the reference space into the space the transforms bring images from.

  • interpolation (str | None) – With transforms, for images: “nearest”, “linear” or “cubic”; None is linear for volumes and nearest for overlays and peaks (whose directions are reoriented).

  • format (str | None) – With transforms: the tool that wrote them, “ants”, “fsl” or “mrtrix”; None guesses from the files (a 4D NIfTI warp can be FSL’s or MRtrix3’s, so it needs format).

  • warp_type (str | None) – With transforms: the warp fields’ type, “deformation” (the default) or “displacement” for MRtrix3, “relative” (the default) or “absolute” for FSL; checked against the fields’ values.

  • fsl_input_path (str | Path | None) – With FSL transforms: the input image of the FLIRT or FNIRT run; defaults to the item when it is an image (to the reference with inverse). Tractograms and surfaces need it.

  • fsl_reference_path (str | Path | None) – With FSL transforms: the run’s reference image; defaults to reference (to the item with inverse). Tractograms and surfaces need it with inverse.

Returns:

The new item; its id names it in the other actions.

Raises:
  • TypeError – If category is not a Category.

  • ValueError – If the file’s extension is not one the category reads, the file cannot be read as that format, an FOD’s number of coefficients fits no SH layout, or the registration cannot be applied (a transform file it cannot read, an image without a reference, an FOD).

  • OSError – If the file cannot be opened.

Return type:

Item

load_matlab(path, preset, *, reference=None, variables=None, tractogram_id=None, max_streamlines=1000000)#

Reads what a MATLAB .mat file holds into new items, as chosen.

The presets read MRIToolkit’s results. TENSOR_FIT (a DTI or DKI fit) adds FA, MD and the eigenvalues as volumes, the first eigenvector as a volume with DTI colours modulated by the FA, and the DWI. FOD_FIT (a GRL or mFOD result) adds its FODs (SH, MRtrix basis) and its fractions and residuals as volumes. TRACTOGRAPHY adds the tracts as a tractogram. MANUAL reads the variables named in variables (paths as in read_matlab, such as “FA”, “DT{1}” or “GRL_Results.FOD”) each as its LoadAs: an image (MRIToolkit’s layout) as a volume, overlay, FODs or peaks; a cell of (N, 3) points as a tractogram; a struct with vertices and faces as a surface; or a cell of one value per point as the values tractogram_id is coloured by. A choice that does not fit its variable’s shape is refused. The file is read before the method returns; sessions reopen the items from the same variables.

Parameters:
  • path (str | Path) – The .mat file.

  • preset (MatlabPreset) – MatlabPreset.TENSOR_FIT, FOD_FIT, TRACTOGRAPHY or MANUAL.

  • reference (str | Path | None) – The grid of files that store none (FOD results, tracts, and images of files without a header): the MRIToolkit fit (.mat) they came from, or a NIfTI or MIF file of its image.

  • variables (dict[str, LoadAs] | None) – For MANUAL, what to read each variable as.

  • tractogram_id (ItemId | None) – The tractogram item coloured by a variable read as LoadAs.POINT_VALUES.

  • max_streamlines (int | None) – As in load.

Returns:

The new items, in the order added.

Raises:
  • ValueError – If the preset does not fit the file, a reference is needed and not given, or a variable cannot be read as chosen.

  • OSError – If a file cannot be opened.

Return type:

list[Item]

add(data, category, *, name=None, source=None, part=None, registration=None)#

Adds an object already in memory, without copying it.

The viewer never changes the object. A volume becomes the main volume, the only visible one. An image starts with its minimum and maximum at its data’s range (scaled by its slope and intercept), and an overlay with its threshold at its minimum. A surface’s colour comes from its name (white yellow, pial red, others light grey), and one with values “curv” is coloured by them. The first item with a grid sets the 2D views’ field of view to that grid’s box and puts the cursor at its centre.

Parameters:
  • data (object) – A Volume for volumes and overlays (3D, or 4D with volumes along the last axis), a Tractogram for tractograms, for FODs a 4D Volume with SH coefficients along the last axis: even degrees only ((lmax + 1)(lmax + 2) / 2 coefficients) or, for an asymmetric FOD, all degrees ((lmax + 1)^2), and for peaks a 4D Volume with x, y and z of each peak’s direction scaled by its amplitude (3 volumes per peak, NaN or 0 where there are fewer peaks), in world coordinates, and for surfaces a Surface.

  • category (Category) – Where the item goes: Category.VOLUMES, OVERLAYS, TRACTOGRAMS, FODS, PEAKS or SURFACES.

  • name (str | None) – The name shown in Layers; “Volume 2” and so on if None.

  • source (Path | None) – The file the object came from, if any.

  • part (MatlabPart | None) – What it was read from inside a MATLAB file source, if so; a session reopens it from there.

  • registration (Registration | None) – The registration data was brought through when read from source, if so; a session applies it again.

Returns:

The new item; its id names it in the other actions.

Raises:
  • TypeError – If category is not a Category.

  • ValueError – If data is not of the category’s type, an FOD’s number of coefficients fits no SH layout, or a peaks image is not 4D with a multiple of 3 volumes.

Return type:

Item

remove(target)#

Removes an item, or every item of a category.

When the main volume is removed, the next volume in Layers order becomes the main volume, and is shown if the removed one was. The views keep their field of view.

Parameters:

target (ItemId | Category) – An item’s id, or a Category to remove all its items.

Raises:
  • TypeError – If target is neither an item id nor a Category.

  • ValueError – If there is no item with that id.

clear()#

Removes every item; the views keep their field of view and cameras.

save_session(path)#

Saves the items and the state of the views to a session file.

The file is JSON (lar.json is the usual extension). It holds each item’s category, name, file (its absolute path and its path from the session file’s folder, so a project folder can be moved) and options, and the view state: cursor, cameras, main volume, selection, maximised view, convention and the overlay and crosshair switches. The application’s settings are not saved. Items added from Python without a file cannot be saved and are left out, with a warning in the log.

Parameters:

path (str | Path) – The session file to write; an existing file is replaced.

Returns:

The names of the items left out, in Layers order.

Raises:
  • OSError – If the file cannot be written.

  • ValueError – If an option holds a value JSON cannot store, such as an infinite number.

Return type:

list[str]

Example

>>> skipped = viewer.save_session("project/view.lar.json")
load_session(path, *, max_streamlines=1000000)#

Replaces the scene with the one a session file holds.

Each file is looked for at its path from the session file’s folder, then at its absolute path, and read before the method returns, as load reads it. A file that is missing or cannot be read, and an option or a view-state field that is no longer allowed, are reported (and logged), and the rest of the session still opens.

Parameters:
  • path (str | Path) – A session file written by save_session.

  • max_streamlines (int | None) – A tractogram with more streamlines keeps a random subset of this size, as in load; None keeps all.

Returns:

The items opened and the problems met, one sentence each.

Raises:
  • SessionError – If the file is not a session, or was saved by a newer Larmor; the scene is then unchanged.

  • OSError – If the session file cannot be read.

Return type:

SessionReport

Example

>>> report = viewer.load_session("project/view.lar.json")
>>> for problem in report.problems:
...     print(problem)
set(target, name, value)#

Changes one option of an item, or of every item of a category.

Showing a volume makes it the main volume and hides the others; setting the Volumes category’s visibility shows or hides the main volume only. A new volume index drops the surface labels its volume does not hold. Minimum, maximum and threshold are in the image’s scaled units. DTI colours need a 4D image with 3 volumes (a direction’s x, y and z), and the image that modulates them must be one of item_choices. A surface’s values to colour by must be one of data_choices; a new one also sets the colormap and range: for “curv” and “sulc” white to black from -0.3 to 0.3, for others the image default over the values’ range. A tractogram’s TSF file (VALUES_FILE) must hold a value per point of its streamlines, and its sampled volume (VALUES_VOLUME) must be one of item_choices; setting either clears the other, colours the tractogram by value and sets the range to the values’ (for a volume, its data’s).

Parameters:
  • target (ItemId | Category) – An item’s id, or a Category to change all its items.

  • name (OptionName) – The option, such as OptionName.COLORMAP.

  • value (object) – The new value, of the option’s type: a bool, a number, a Colormap, a path for a lookup table (”” for the built-in colours) or a TSF file (”” for none), label numbers for SURFACE_LABELS, which must be among the overlay’s labels, or another item’s id (or None) for an option that names an item, such as OptionName.MODULATE or VALUES_VOLUME, or a name (or None) for OptionName.COLOUR_BY. A tractogram’s INCLUDE_MASKS, EXCLUDE_MASKS and WITHIN_MASKS are items’ ids, each one of item_choices, and INCLUDE_SPHERES, EXCLUDE_SPHERES and WITHIN_SPHERES are (x, y, z, radius) in world coordinates, mm.

Raises:
  • TypeError – If target or name is of the wrong type.

  • OptionError – If the items have no such option, the value is outside the option’s range or choices, the option (such as the volume index) is set per item and target is a category, DTI colours are asked of an image without 3 volumes, the item named is not one the option can name, a surface has no such values, or a TSF file cannot be read or does not match the tractogram.

  • ValueError – If there is no item with that id.

Example

>>> viewer.set(Category.OVERLAYS, OptionName.OPACITY_2D, 0.5)
add_mask(item_id, mask_id, *, role=RegionRole.INCLUDE)#

Adds a mask to the regions a tractogram’s streamlines are filtered by.

With the filter on (OptionName.REGION_FILTER, on by default), only the streamlines that pass through every include region, through no exclude region and stay within every within region are drawn; a point is inside a mask when it lies in a voxel whose value rounds to a non-zero integer. A streamline passes through a region when one of its points is inside it, and stays within it when all of them are. The subset and the points per streamline then apply to the streamlines kept.

Parameters:
  • item_id (ItemId) – The tractogram’s id.

  • mask_id (ItemId) – The mask: a volume or an overlay with one volume, on any grid, one of item_choices.

  • role (RegionRole) – RegionRole.INCLUDE to keep the streamlines that pass through it, EXCLUDE to drop them, WITHIN to keep only those that stay within it.

Raises:
  • ValueError – If there is no item with either id.

  • TypeError – If role is not a RegionRole.

  • OptionError – If the item is not a tractogram or the mask is not one it can be filtered by.

add_sphere(item_id, radius, *, centre=None, role=RegionRole.INCLUDE)#

Adds a sphere to the regions a tractogram’s streamlines are filtered by.

As add_mask; a point is inside the sphere when it is at most radius from the centre.

Parameters:
  • item_id (ItemId) – The tractogram’s id.

  • radius (float) – The sphere’s radius in mm, positive.

  • centre (tuple[float, float, float] | None) – Its centre in world coordinates, mm; the cursor if None.

  • role (RegionRole) – RegionRole.INCLUDE to keep the streamlines that pass through it, EXCLUDE to drop them, WITHIN to keep only those that stay within it.

Raises:
  • ValueError – If there is no item with that id.

  • OptionError – If the item is not a tractogram, the centre or the radius is not a finite number, or the radius is not positive.

clear_regions(item_id)#

Removes every region a tractogram is filtered by, so all are drawn.

Parameters:

item_id (ItemId) – The tractogram.

Raises:
region_selection(item_id)#

Which of a tractogram’s streamlines its regions keep.

It runs the same filter as the drawing, once per change of the regions: the result is kept until they change.

Parameters:

item_id (ItemId) – The tractogram’s id.

Returns:

(S,) bool, one per streamline of the item’s tractogram, True for those kept; None if the options keep every streamline (the filter is off or there are no regions).

Raises:
Return type:

ndarray | None

kept_streamlines(item_id)#

How many of a tractogram’s streamlines its regions keep.

Counted over the streamlines loaded, before the subset is taken.

Parameters:

item_id (ItemId) – The tractogram.

Returns:

The number of streamlines kept.

Raises:
Return type:

int

labels(item_id)#

The labels in an overlay’s shown volume, as a parcellation holds them.

The surfaces of the 3D view are chosen among these (SURFACE_LABELS).

Parameters:

item_id (ItemId) – An overlay’s id.

Returns:

The values other than 0 in the volume at the overlay’s volume index, in scaled units rounded to whole numbers, sorted; none for an image with more distinct values than a parcellation can show (8192).

Raises:

ValueError – If there is no item with that id, or it is not an overlay.

Return type:

tuple[int, …]

set_default(category, name, value)#

Sets the value an option starts with on the items added to a category.

Items already in the scene keep their value. The Settings panel uses it for the default interpolation of new images.

Parameters:
  • category (Category) – The category whose new items start with the value.

  • name (OptionName) – The option.

  • value (object) – Its starting value, checked as set checks it.

Raises:
  • TypeError – If category or name is not its enum.

  • OptionError – If the category has no such option, the option is set per item, or the value is not allowed.

item_choices(item_id, name)#

The items an option that names an item can name, for one item.

For OptionName.MODULATE: the other volumes and overlays that are 3D and on the same grid (shape and affine) as the item. For OptionName.VALUES_VOLUME, and the masks a tractogram is filtered by (INCLUDE_MASKS, EXCLUDE_MASKS, WITHIN_MASKS): the volumes and overlays with one volume (3D, or 4D with a single volume), on any grid.

Parameters:
Returns:

The items, in Layers order.

Raises:
  • TypeError – If item_id or name is of the wrong type.

  • ValueError – If there is no item with that id.

  • OptionError – If the item has no such option, or it names no item.

Return type:

list[Item]

data_choices(item_id, name)#

The names an option that names some of an item’s data can take.

For OptionName.COLOUR_BY: the surface’s values per vertex, one number per vertex each, such as “curv” or “thickness”.

Parameters:
  • item_id (ItemId) – The item whose option it is.

  • name (OptionName) – An option that names some of the item’s data.

Returns:

The names, in the data’s order; None, for no data, is always allowed.

Raises:
  • TypeError – If item_id or name is of the wrong type.

  • ValueError – If there is no item with that id.

  • OptionError – If the item has no such option, or it names no data.

Return type:

list[str]

select(target)#

Selects an item or a category, as a click in Layers does.

The selection is what the Options panel shows, and the image the left and right arrows step through.

Parameters:

target (ItemId | Category | None) – An item’s id, a Category, or None to select nothing.

Raises:
  • TypeError – If target is neither an item id nor a Category.

  • ValueError – If there is no item with that id.

move_cursor(position)#

Moves the cursor, and so the crosshair and the slices, to a position.

Parameters:

position (tuple[float, float, float]) – The world position (x, y, z) in mm, RAS+. It may lie outside the images.

Raises:

ValueError – If position is not three finite numbers.

step_slice(view, n)#

Moves a 2D view’s slice by n steps along the view’s axis.

A step is the reference grid’s voxel size along the world axis closest to the view’s (x for sagittal, y for coronal, z for axial), or 1 mm with no grid. Positive n moves towards right, anterior or superior.

Parameters:
Raises:
select_view(view)#

Makes a view the selected one, as a click in it does; shortcuts act there.

Parameters:

view (ViewKind) – The view.

Raises:

TypeError – If view is not a ViewKind.

step_volume(n)#

Moves a 4D image’s volume index by n, as the left and right arrows do.

The image is the selected one if it is 4D, else the main volume. The index stops at the first and the last volume; without a main volume, nothing happens.

Parameters:

n (int) – The number of volumes, negative to go back.

Raises:

TypeError – If n is not a whole number.

zoom(view, factor, *, about=None)#

Zooms a view in or out, keeping a point where it is on the screen.

The zoom stays within ZOOM_RANGE (0.25 to 64 times the field of view at zoom 1). The 3D view always zooms about its centre.

Parameters:
  • view (ViewKind) – The view to zoom.

  • factor (float) – How much to multiply the zoom by: above 1 zooms in, below 1 zooms out.

  • about (Vec3 | None) – The world position (mm) that stays in place, such as the point under the mouse; the view’s centre if None. Not allowed for the 3D view.

Raises:
  • TypeError – If view is not a ViewKind.

  • ValueError – If factor is not a positive number, about is not three finite numbers, or about is given for the 3D view.

pan(view, right, up)#

Moves what a 2D view shows, as a drag does.

Parameters:
  • view (ViewKind) – ViewKind.AXIAL, CORONAL or SAGITTAL.

  • right (float) – How far the view’s centre moves towards the screen’s right, in mm (negative: left).

  • up (float) – How far it moves towards the screen’s top, in mm (negative: down).

Raises:
  • TypeError – If view is not a ViewKind.

  • ValueError – If view is the 3D view, or right or up is not a finite number.

reset_camera(view)#

Shows a view’s whole field of view again, at zoom 1 and centred.

The 3D view also returns to its starting direction.

Parameters:

view (ViewKind) – The view to reset.

Raises:

TypeError – If view is not a ViewKind.

rotate_camera(right, up)#

Turns the 3D view’s scene, as a drag in that view does.

The turn is about the camera’s own axes, so it never locks up when looking straight down.

Parameters:
  • right (float) – Degrees to turn the scene towards the screen’s right (about the screen’s up axis).

  • up (float) – Degrees to turn it towards the screen’s top (about the screen’s right axis).

Raises:

ValueError – If right or up is not a finite number.

set_camera(view, preset)#

Moves the 3D view’s camera to a standard position, keeping its zoom.

Parameters:
  • view (ViewKind) – ViewKind.THREE_D, the only view with camera positions.

  • preset (CameraPreset) – Axial (from above), coronal (from the front) or sagittal (from the subject’s right).

Raises:
  • TypeError – If view is not a ViewKind or preset not a CameraPreset.

  • ValueError – If view is a 2D view.

set_convention(convention)#

Shows the subject’s right on the screen’s right or on its left.

Each 2D view stays centred on the same place.

Parameters:

convention (Convention) – Convention.RAS (neurological, right on the right) or Convention.LAS (radiological, right on the left).

Raises:

TypeError – If convention is not a Convention.

view_centre(view)#

The world position at the centre of a 2D view, in its slice plane.

Parameters:

view (ViewKind) – ViewKind.AXIAL, CORONAL or SAGITTAL.

Returns:

The position (x, y, z) in mm, RAS+.

Raises:
Return type:

Vec3

readout()#

What the crosshair reports, as the 2D views show it.

Returns:

The cursor’s position (mm, RAS+) and, with a main volume, its name, the nearest voxel (i, j, k, with the volume index for a 4D image) and the value there in scaled units, interpolated if the volume is shown interpolated; voxel and value are None outside its grid.

Return type:

Readout

toggle_maximised(view)#

Makes a view fill the window, or, if it already does, shows all four.

The view filling the window is also selected, so the shortcuts act on it.

Parameters:

view (ViewKind) – The view.

Raises:

TypeError – If view is not a ViewKind.

set_view_state(state)#

Sets the whole state of the views at once, as a session restores it.

The main volume keeps its visibility and the other volumes are hidden, so at most the main volume is shown. Zooms are kept within ZOOM_RANGE and the 3D camera’s directions are made unit and at right angles.

Parameters:

state (ViewState) – The new view state; its items must be in the scene.

Raises:
  • TypeError – If state is not a ViewState, or one of its fields is not of its type.

  • ValueError – If the main volume is not a volume in the scene, there are volumes and no main volume, the selected item is not in the scene, or a position, camera or field of view is not finite.

toggle_overlay()#

Shows or hides the text and colour bars drawn over the views.

The text is the orientation letters at the edges and the crosshair’s readout.

toggle_crosshair()#

Shows or hides the crosshair in the 2D views.

screenshot(view, path, *, size=(800, 800), scale=1.0, overlay=None, transparent=False)#

Draws one view, or all of them, off screen, as the window shows them.

Needs no window and no Qt, only the viewer’s drawing library (pygfx) and a GPU or a software renderer. With a window open, the image is drawn separately, at the given size, and the window is not changed. To draw many images of one scene, an OffscreenRenderer (in larmor.viewer.render.offscreen) is faster: it is set up once.

Parameters:
  • view (ViewKind | None) – The view to draw, or None for the whole window’s layout: the maximised view if there is one, else the four views in the window’s 2 x 2 grid (axial, coronal; sagittal, 3D), with a thin grey line between them.

  • path (str | Path) – The image file to write; its extension sets the format (.png, .jpg, .tif, …). An existing file is replaced.

  • size (tuple[int, int]) – Each view’s width and height in logical pixels, the units of the window’s views; text and lines keep their size in them.

  • scale (float) – Pixels per logical pixel in the image, for example 2 for twice the resolution with the same layout.

  • overlay (bool | None) – Whether to draw the information overlay (text, labels and colour bars); None follows toggle_overlay’s switch, which the screenshot leaves as it is.

  • transparent (bool) – Whether the background is transparent (an RGBA image) rather than the views’ background colour; needs PNG or TIFF.

Returns:

The path written. The image is RGB, or RGBA if transparent; each view in it is size times scale pixels.

Raises:
  • ViewerUnavailableError – If the viewer’s dependencies are not installed.

  • TypeError – If view is neither a ViewKind nor None, or overlay or transparent is not a bool.

  • ValueError – If size or scale is not positive, the image is larger than the GPU draws, or the extension is not an image format (or is JPEG with a transparent background).

  • OSError – If the file cannot be written.

Return type:

Path

Example

>>> viewer.screenshot(ViewKind.AXIAL, "axial.png", size=(600, 600))
>>> viewer.screenshot(None, "all.png", scale=2, transparent=True)
screenshot_views(path, *, size=(800, 800), scale=1.0, overlay=None, transparent=False)#

Draws the three 2D views off screen, each into its own file.

The images are those screenshot draws of each 2D view, drawn with one renderer, so they are faster than three screenshots.

Parameters:
  • path (str | Path) – The name the files are made from, the view’s name added to its stem: “fig.png” gives “fig_axial.png”, “fig_coronal.png” and “fig_sagittal.png”. Existing files are replaced.

  • size (tuple[int, int]) – Each view’s width and height in logical pixels.

  • scale (float) – Pixels per logical pixel in the images.

  • overlay (bool | None) – Whether to draw the information overlay; None follows toggle_overlay’s switch, which is left as it is.

  • transparent (bool) – Whether the background is transparent (RGBA images); needs PNG or TIFF.

Returns:

The paths written – axial, coronal, sagittal.

Raises:
Return type:

tuple[Path, …]

Example

>>> viewer.screenshot_views("fig.png", scale=2)
record_rotation(path, *, size=(800, 800), scale=1.0, speed=30.0, duration=12.0, fps=30, overlay=None, transparent=False, on_progress=None)#

Records the 3D view turning, off screen, as an animated WebP or GIF.

The scene turns about the screen’s up axis, starting from the 3D view’s camera, which is left as it is: with a window open, its 3D view does not move. The frames are written as they are drawn, so a long video of large frames does not fill the memory (a GIF keeps each frame as 8-bit colour until the end).

Parameters:
  • path (str | Path) – The file to write: .webp or .gif. An existing file is replaced once the video is complete, and kept if it is cancelled.

  • size (tuple[int, int]) – The 3D view’s width and height in logical pixels.

  • scale (float) – Pixels per logical pixel in the frames.

  • speed (float) – Degrees the scene turns per second, towards the screen’s right; negative turns it to the left.

  • duration (float) – Seconds of video; the default, at the default speed, is one full turn.

  • fps (int) – Frames per second, a whole number; a GIF takes at most 50 (it stores frame times in hundredths of a second, so at 30 its frames last 30 or 40 ms, 33.3 ms on average).

  • overlay (bool | None) – Whether to draw the information overlay; None follows toggle_overlay’s switch.

  • transparent (bool) – Whether the background is transparent; needs WebP.

  • on_progress (Progress | None) – Called after each frame with the number of frames drawn and their total, for example to show progress; it returns True to go on, or False to cancel.

Returns:

The path written, or None if on_progress cancelled the video.

Raises:
  • ViewerUnavailableError – If the viewer’s dependencies are not installed.

  • TypeError – If overlay or transparent is not a bool, speed or duration is not a real number, or fps is not a whole number.

  • ValueError – If size or scale is not positive, the frames are larger than the GPU draws, the extension is neither .webp nor .gif (or is .gif with a transparent background or fps above 50), speed is not finite, duration is not positive, or fps is not positive.

  • OSError – If the file cannot be written.

Return type:

Path | None

Example

>>> viewer.record_rotation("turn.webp", size=(600, 600))
>>> viewer.record_rotation("half.gif", speed=45, duration=4, fps=20)
exception larmor.viewer.ViewerUnavailableError#

The viewer cannot start on this machine.

larmor.viewer.view(viewer=None, *, volumes=None, overlays=None, tracts=None, fods=None, peaks=None, surfaces=None, max_streamlines=<larmor.viewer.loading.Default object>, session=None, block=True, mcp=False, mcp_port=None)#

Opens the viewer’s window on files or objects, given by category.

Items appear in the order given. Files are read in the background, like files opened from the window, and appear as each one is read; a file that cannot be read shows a message. Objects are never copied: those given before any file of their category are added at once, the others after the files before them. Calling view again with the same viewer brings its window back and adds to it. A session replaces what the viewer shows; the files and objects given with it are added after its items.

Parameters:
  • viewer (Viewer | None) – The viewer to show; a new one if None.

  • volumes (Sources | None) – Volumes: a path or a Volume, or a list of them.

  • overlays (Sources | None) – Overlays (masks, maps, parcellations): paths or Volume objects.

  • tracts (Sources | None) – Tractograms: paths or Tractogram objects.

  • fods (Sources | None) – FODs, drawn as glyphs in the 2D views: paths or 4D Volume objects of SH coefficients, in the tournier basis unless their basis option says otherwise.

  • peaks (Sources | None) – Peaks images, as lar peaks writes them: paths or 4D Volume objects with x, y and z of each peak’s direction scaled by its amplitude (3 volumes per peak). They are drawn as lines in the 2D views.

  • surfaces (Sources | None) – Surfaces: GIfTI (.gii) or FreeSurfer files (such as lh.white), or Surface objects. A FreeSurfer surface’s curvature (lh.curv in its folder) and cortex label (../label/lh.cortex.label) are read with it when they exist.

  • max_streamlines (int | None | Default) – A tractogram file given here with more streamlines is reduced to a random subset of this size when read; the same file always gives the same subset. None keeps all. If not given, the read limit of the Settings panel (1,000,000 unless changed), which files opened later from the window use too. Objects are never reduced.

  • session (str | PathLike[str] | None) – A session file saved from the viewer (File > Save Session or Viewer.save_session): its files are read in the background, then its options and views are restored. Missing files are reported in a message box, and the rest still opens.

  • block (bool) – Wait until the window is closed. With False, return at once: in IPython or Jupyter, run %gui qt first so the window stays live; in a script, call wait to let the files load.

  • mcp (bool) – Serve the viewer’s actions to agents over MCP, at http://127.0.0.1:<port>/mcp; the URL and the token that requests need are printed. Tool calls run while Qt’s events run: while the window blocks, or with %gui qt.

  • mcp_port (int | None) – The port for mcp, which it implies; the port in the Settings window (8765 unless changed) if None. If the port is taken, a message is printed and the window opens without the server.

Returns:

The viewer, whose actions change what the window shows.

Raises:
  • ViewerUnavailableError – If the viewer cannot start on this machine.

  • ValueError – If an object is not of its category’s type, an FOD’s number of coefficients fits no SH layout, a peaks object does not hold 3 volumes per peak, max_streamlines is negative, or mcp_port is not between 1024 and 65535.

  • SessionError – If session is not a session file this version reads.

  • OSError – If the session file cannot be read.

Return type:

Viewer

Example

>>> from larmor.viewer import view
>>> viewer = view(volumes="t1.nii.gz", tracts=["cst.tck", "af.tck"])
larmor.viewer.wait(viewer, timeout=None)#

Waits until the files given to view or opened in the window are loaded.

Needed after view(..., block=False) in a script, where nothing else runs Qt’s events; in IPython or Jupyter with %gui qt, files load on their own.

Parameters:
  • viewer (Viewer) – The viewer whose window loads the files.

  • timeout (float | None) – The longest wait in seconds; None waits as long as it takes.

Raises:

TimeoutError – If the files are still loading after timeout seconds.