Macro for Grid/Collection stitching

Hi all,

I am new to writing Macros and I have been trying to create a macro that will automatically find subfolders, stitch all the images in that folder and save the stitched image in a new location. Right now, this is what I have:

// Stitching 3x3 grid for a single channel
input = "/Users/almou/Desktop/Correct_Name/Channel1";
output = "/Users/almou/Desktop/Stitched_Channels";
// Setting up the file names
setBatchMode(true)
list = getFileList(input);
for(i = 0; i < list.length; i+8) {
	wellIndexStart = indexOf(list[i], "FV10__20190522_143413_"); // This finds the index of the file name where the X, Y coordinated begin
	wellIndexEnd = indexOf(list[i], "_10"); // This is the index of the file name where the X, Y coordinates end 
	wellCoord = substring(list[i], wellIndexStart+9, wellIndexEnd); // The string of X, Y coordinates from the file name
	genericFilename = replace(list[i], "Y001_X001", "Y{iii}_X{iii}"); // Replace the coordinate numbers with a variable for the stitch plugin
	}
setBatchMode(false)
// Running the stitch plugin for each file
functionaction(input,output,genericFilename,list[i],wellCoord) {
	open(input+filename)
	run("Grid/Collection stitching", "type=[Filename defined position] order=[Defined by filename] grid_size_x=3 grid_size_y=3 tile_overlap=0 first_file_index_x=1 first_file_index_y=1 directory= " + input + " file_names= " + genericFilename + " output_textfile_name= " + wellCoord + "_Channel_Stitched.txt fusion_method=[Linear Blending] regression_threshold=0.30 max/avg_displacement_threshold=2.50 absolute_displacement_threshold=3.50 computation_parameters=[Save memory (but be slower)] image_output=[Fuse and display]");
run("Install...");
saveas("tif", output + filename);
close();
}

The folder that contains the subfolders is “Correct_Name” and within that folder there are 30 subfolders each named with the corresponding channel (e.g. “Channel1”). Every folder is named: FV10__20190522_143413_Y001_X001_1002
with the Y and X coordinate numbers changing to determine which grid tile it is and the last number changing to correspond with what channel it is (thus every file in a single “Channel#” folder will have the same name besides the Y and X coordinates.

Ideally, this code would find each “Channel#” folder, stitch the 3x3 image and save the stitched images in the “Stitched_Channels” folder all automatically. Right now when I hit run nothing happens so unfortunately I know I’m far off.

Since this is my first time working with macros I’d appreciate any advice or thoughts people have!

Thank you,
Alexa

A couple of things to start with, have you tried Debugging your macro in a Step by step fashion (search the page for debugging)? That should show you what is happening at each line, for example if your path is wrong and images aren’t opening, you would get to see that. I will also post some code where I go through a folder structure later. It has a completely different purpose than yours, but maybe it will give you some ideas.

Also, I don’t know about everyone else, but I generally run into problems copying out code directly from the forum that isn’t formatted as code. Or at least it takes extra steps to fix. Code snippits should be enclosed using this tool.
image

1 Like

I was not aware of the debugging function, I will try that now.

I fixed the format on the code.

Thank you!

Great! Here is the code for another macro that searches through subfolders to combine various files, all of which have the same name but are located in different folders. Intended for putting together images exported from InForm for the Vectra. Not sure how useful it will be to you, but it might give you some ideas.

dir1 = getDirectory("Choose Source Directory ");
dir2 = getDirectory("Choose Destination Directory ");

setBatchMode(true);
channelList = getFileList(dir1);
batchList = getFileList(dir1+channelList[0]);
//Open groups of files, one per channel for a set
for (j=0; j<batchList.length; j++){
	imageList = getFileList(dir1+channelList[0]+batchList[j]);
	for (k=0; k<imageList.length; k++){
		for (i=0; i<channelList.length; i++) {
			//print(dir1+channelList[i]+batchList[j]+imageList[k]);
			open(dir1+channelList[i]+batchList[j]+imageList[k]);
			rename(channelList[i]);
			run("8-bit");
			run("Properties...", "channels=1 slices=1 frames=1 unit=um pixel_width=0.5 pixel_height=0.5 voxel_depth=1");
		}
		run("Images to Stack", "name=["+imageList[k]+"] title=[] use");
		run("Properties...", "channels=6 slices=1 frames=1 unit=µm pixel_width=0.5000000 pixel_height=0.5000000 voxel_depth=1.0000000");
		saveAs("TIFF", dir2+imageList[k]);
		while (nImages>0) { 
          selectImage(nImages); 
          close(); 
        } 
	}
}

I used components of that code and now I have this:

input = getDirectory("Choose Source directory");
output = getDirectory("Choose Destination Directory");

setBatchMode(true);
channelList = getFileList(input);
batchList = getFileList(input+channelList[0]);
for (j=0; j<batchList.length; j++){
	imageList = getFileList(input+channelList[0]+batchList[j]
	for (k=0; k<imageList.length; k++){
	wellIndexStart = indexOf(batchList[k], "FV10__20190522_143413_"); // This finds the idenx of the file name where the X, Y coordinated begin
		wellIndexEnd = indexOf(batchList[k], "_10"); // This is the index of the file name where the X, Y coordinates end
		wellCoord = substring(batchList[k], wellIndexStart+22, wellIndexEnd); // The string of X. Y coordinates from the file name
		genericFilename = replace(list[k], wellCoord, "Y{yyy}_X{xxx}"); // Replace the coordinate numbers with a variable for the stitch plugin
		run("Grid/Collection stitching", "type=[Filename defined position] order=[Defined by filename         ] grid_size_x=3 grid_size_y=3 tile_overlap=0 first_file_index_x=1 first_file_index_y=1 directory= " + input + " file_names= " + genericFilename + ".tif output_textfile_name= " + wellCoord + "_Channel_Stitched.txt fusion_method=[Linear Blending] regression_threshold=0.30 max/avg_displacement_threshold=2.50 absolute_displacement_threshold=3.50 computation_parameters=[Save memory (but be slower)] image_output=[Fuse and display]");
saveAs("Tiff", output + filename);
close()}
}

I keep getting the error: ‘)’ expected in line 13:

However, my 13th line – (k=0; k<imageList.length; k++){ – is identical to your code… I am not sure how to troubleshoot this error. Any thoughts would be appreciated!

Thank you,
Alexa

The problem is that the previous line is missing a semicolon, I think.

1 Like