Multistackreg macro


I’m trying to do 4D registration, described here: 4D registration, possible?.

I have an idea about how to do it, but I need to be able to use the multistackreg plugin instead of just stackreg, in a macro. Does anyone know if this is possible?

I use a macro to run stackreg on all stacks in a directory. What I need is to run multistackreg on that directory and make it save the transformation matrices for each stack. Then I need to be able to do the same on another directory with the same number of stacks, but instead of having multistackreg actually registering the stacks, I want it to just load the transformation matrices from the first run, and apply them to the corresponding track in this directory.

Currently I use a macro that asks for a directory and then runs stackreg on all files in it, saving the new stacks. The part of the macro that loads stackreg looks like this:

function processFile(path) {
    if (endsWith(path, ".tif")) {
        run("StackReg", "transformation=[Rigid Body]");

Does anyone have a clue about how to instead make it do what I described above? As you might guess, I can’t code at all.

Help greatly appreciated!



First, some links for completeness (other users might not necessarily know about MultiStackReg, as it is not part of Fiji (yet)):

@David have you tried the macro recorder with MultiStackReg?



I have not tried to record a macro with it, yet. Will do.

What is the difference between MultiStackReg and MultiStackRegistration? I can’t seem to find it on the website.



You can see it in detail in the commits section of the github repository. From the commit messages and the first section of the README I’d say probably mostly minor changes for scripting.

Since there is no compiled version available I haven’t tried it myself yet - didn’t have the time yet to build the plugin from its source.

1 Like


Hi @David, @ehrenfeu,

Here is the download link for the jar file of MultiStackRegistration.

… and its Javadoc

EDIT, Mar. 16, 2016
The github repo has releases where you can download the plugin JAR file.

The difference to MultiStackReg is that many of its methods are exposed to be ready for use for scripting with Jython or Javascript, and others.

With IJ Macro, I’ve never tried but just try using macro recorder, to see if the recorder captures parameter settings.




Ah, great news @Kota - thank you very much!



The IJ macro recorder properly captures parameters for the “old” MultiStackReg, for example this code below aligns a two-channel stack using the first one as the reference (somehow I couldn’t make it work in a single run, hence the splitting and merging):

imgname = getTitle();
run("Split Channels");
c1 = "C1-" + imgname;
c2 = "C2-" + imgname;

getDateAndTime(year, month, dayOfWeek, dayOfMonth,
	hour, minute, second, msec);
tmpfile  = getDirectory("temp");
tmpfile += "MSR-" + year + "-" + month + "-" + dayOfMonth +
	"_" + hour + "-" + minute + "-" + second + ".txt";
run("MultiStackReg", "stack_1=" + c1
	+ " action_1=Align"
	+ " file_1=[" + tmpfile + "]"
	+ " stack_2=None"
	+ " action_2=Ignore"
	+ " file_2=[]"
	+ " transformation=Translation save");

run("MultiStackReg", "stack_1=" + c2 +
	" action_1=[Load Transformation File]" +
	" file_1=[" + tmpfile + "]" +
	" stack_2=None" +
	" action_2=Ignore" +
	" file_2=[]" +
	" transformation=Translation");

run("Merge Channels...", "c1=" + c1 + " c2=" + c2 + " create");


Wow, thanks! Trying it now. I will run it on a directory of many stacks, and the macro I’m using for that opens all stacks, but only one stack at once and runs multistackreg on it (hopefully). Or at least that’s how I interpret the code. What would I put as “stack_1=” instead of c2 that you put, if I want it to be run on the open stack? That name will obviously be different for each stack since they all are from different timepoints.

EDIT: Got it to work, just used “path” as “stack_1”. But now the problem is that for each stack, it asks me where (and with what name) I want to save the transformation matrices. Is there a way to automate this? I can see that you did this in your code somehow, but mine does not look the same, see below.

       dir = getDirectory("Choose a Directory ");
       count = 0;
       n = 0;
       //print(count+" files processed");
       function countFiles(dir) {
          list = getFileList(dir);
          for (i=0; i<list.length; i++) {
              if (endsWith(list[i], "/"))
       function processFiles(dir) {
          list = 
          for (i=0; i<list.length; i++) {
              if (endsWith(list[i], "/"))
              else {
                 showProgress(n++, count);
                 path = dir+list[i];
      function processFile(path) {
           if (endsWith(path, ".tif")) {
        run("MultiStackReg", "stack_1=[path] action_1=Align file_1=[] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body] save");

From your code, I’m guessing that I need something after “file_1=” where you put " + tmpfile + ". But what? I tried creating a tmpfile but it didn’t really work. I guess the best for me would just to have the macro name the transformation matrices exactly the same as the file it’s workin on but just add .txt to the file.

Your code looks different from mine from multistackregistration. And what’s with the plus-signs you have in your code?

EDIT2: I tried the following:

     function processFile(path) {
           if (endsWith(path, ".tif")) {
        matrices = path + ".txt";
        run("MultiStackReg", "stack_1=[path] action_1=Align file_1=[matrices] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body] save");

But I just got “Error writing to file” when running the macro.



@David, you’re partially answering your own question yourself with your code:

The plus signs are string concatenation. By removing them in your run() command, your variables like path do not get evaluated and therefore don’t have any meaning. Hence the writing error.

I strongly recommend reading the Introduction into Macro Programming page of the Fiji-wiki, in particular section 2.1.



Thanks. I must say I already read the introduction and it wasn’t super easy to understand why it didn’t work anyway. The examples in the intro is a bit simpler than this code (also, I might not be clever enough). Anyway, I re-wrote the code, largely imitating your way of concatenating and now it works! It correctly runs the registration and creates matrices!

Now I will try to write the other script that will load them. I’ll be back!

EDIT: Getting that to work wasn’t that hard. Thanks for your help @ehrenfeu! Having your code to look at really helped.


Adding hints about variable in macro language

Hi David,
I am trying to add multistackreg in my macro too, Can you share your final code that worked in yours, please?
That would help me a lot , I am having the same problem than you

Thanks in advance