Matlab Module step-by-step debugging not working

Using Windows 10, Slicer 4.10.2, MATLAB 2018a

Expected behavior: Custom Matlab module execution stops at breakpoint
What happens: Module execution is not affected by breakpoints

I read the instructions here https://www.slicer.org/wiki/Documentation/Nightly/Extensions/MatlabBridge for ‘step-by-step’ debugging, but when I run my module from Slicer a connection cli_commandserver is made and the module finishes execution without stopping at the breakpoints, and then the connection is closed.

I also can’t seem to edit my Matlab functions or scripts (not the .xml file) and see changes in Slicer instantly, I always have to restart slicer to notice any changes. This seems different from the behaviour in this video: https://www.youtube.com/watch?v=8LijOcv3GDY&feature=youtu.be

Thanks!

Okay I fixed it, turns out I was adding breakpoints to files in the incorrect folder!

However I’ve run into two new problems:
My matlab module takes two directory paths as inputs. At the moment I am defining them as ‘strings’ within the .xml file. However when I’m reading them in the matlab function with inputParams.stringName I only receive an escape character instead of the full string, which I defined as something like “C:/Users/slicer-module-test/”

Second issue:
Even though my matlab module does not take an image as input, it outputs 2 images. These images are generated by some matlab function which are processing .mha files saved in a separate directory.
However, I can’t seem to correctly read the output volumes in my matlab module function.
I’m using
cli_imageread(inputParams.outputvol1)
to read the file, but this returns an error because inputParams.outputvol1 refers to a nonexistent the path to a vtkMRMLScalarVolumeNode.nrrd file. Is this because it is an empty scalar volume node that I create in Slicer before running module?

My full code is:

function outputParams=USSegmentAndReconstruct(inputParams)

clc
cd(userpath)
startup %this adds relevant directories to my path

num_files = inputParams.num_files;      %input integer
data_dir = inputParams.data_dir;           %input directory string
config_fname = inputParams.config_fname;        %input directory string

combinedVol = cli_imageread(inputParams.combinedVol);      %output volume1 (I get an error here)
US_dist = cli_imageread(inputParams.US_dist);                      %output volume2

[combinedVol.pixelData, US_dist.pixelData] = someImageProcessing(num_files, data_dir, config_fname);

cli_imagewrite(inputParams.combinedVol, combinedVol);
cli_imagewrite(inputParams.US_dist, US_dist);

I can’t quite figure out what I am doing wrong here, but I guess it has something to do with the fact that both inputParams.combinedVol and inputParams.US_dist do not contain any data… yet

What escape character do you get? Can you pass a simple string that does not contain spaces, slashes, and quotes?

You need to create image files by the names that Slicer provides. If you must create .mha file then change the module descriptor xml file so that Slicer generates a file with .mha extension.

One issue for sure is that you use inputParams.combinedVol and inputParams.US_dist both as input and output volumes. If they are output volumes then don’t call cli_imageread on them because they don’t exist (you have to create them).

The escape character was: \
I no longer have that issue after removing “quotation marks” and using <directory> tags instead of <string> tags in the .xml file.

I don’t quite understand how to do this. How do I create an empty .mha image which I can write to through the matlab function, and how is it supposed to be defined in the .xml file?

I don’t know how you create .mha image from scratch (I’m sure there are .mha writer matlab scripts). I would recommend using the .nrrd reader and writer scripts that are bundled with the MatlabBridge. They are tested to work well with Slicer. Here are examples of how to create .nrrd image file from scratch:

1 Like

Thanks Andras, I understand now and got it to work.

For reference, I’ve been using mha_read_volume.m, mha_read_header.m, and mha_write_volume.m Matlab functions from https://github.com/PlusToolkit/PlusMatlabUtils/tree/master/MatlabMetafileIO to read and write .mha volumes.

However since MHA files are not one-indexed (and in my case are in RAI coordinate system), I had to write the img.ijkToLpsTransform like this:

outputVolume.ijkToLpsTransform = [info.PixelDimensions(1), 0, 0, info.Offset(1)-info.PixelDimensions(1); ...
    0, info.PixelDimensions(2), 0, info.Offset(2)-info.PixelDimensions(2); ...
    0, 0, info.PixelDimensions(3), info.Offset(3)-info.PixelDimensions(3); ...
    0, 0, 0, 1];

Where info is the header information output/input for mha_read_header/mha_write_volume.m

1 Like

Thanks for the update.

Note that AnatomicalOrientation = RAI in a metaimage file means that coordinates are defined in LPS coordinate coordinate system. Slicer uses LPS coordinate system for files but otherwise uses RAS coordinates.

Indeed, you need to pay attention to Matlab’s unconventional 1-based array indexing. The nrrd reader/writer class bundled with MatlabBridge extension takes care of this as shown here.