Getting rid of a pop-up in a macro

Hello every one!

I am trying to wirte a macro to count TUNEL positive cells (in a IF TUNEL staining done withe a kit from Roche).

I co-stained for F4/80 and dapi, both of which I need to get rid of for the automated counting.
So as a first step I wanted to change the .tif images from RGB color to RGB stack.

Now the problem is, that if using the command “run(“RGB Stack”)”, a pop-up window appears: “Supported Conversions: “list”” and one needs to click an “ok” button for further processing. But at the same moment the macro is finished, without carrying out any further steps.

I just started using macros. So sorry for the basic question. If anybody knows how to avoid the pop-up window, I would be great full for any advice!

All the Best
Jan

Hello Jan -

The pop-up window is warning you that the image you are trying
to convert to an RGB stack is not an RGB image. This does,
indeed, cause the macro to abort. You will need to only process
actual RGB images (or check in your code that you have an RGB
image).

This IJM macro illustrates the issue:

// the sample "Clown" image is RGB so "RGB Stack" works
run ("Clown (14K)");
run ("RGB Stack");

// the sample "Blobs" image is 8-bit grayscale so
// "RBG Stack" pops up the warning message
// (and aborts the macro)
run ("Blobs (25K)");
run ("RGB Stack");

Thanks, mm

Hi @Jay_N,

That popup message is indicative of a wrong input image type to perform a conversion. Are you sure the image you’re trying to convert is actually RGB (24bit)?

You can check that in the image header:
imagen

Cheers,
Nico

Hi @mountain_man! Sorry for the collision! I didn’t notice you were also writing. :blush:

Thanks a lot! In a way it worked. Now if using the Process -> Batch -> Macro function. It does its job.

But if I wanne use the script example for my purposes it tells me “there are no images open”.

Also if using the batch-process window. How could I make the script save every ROI as a zip file with the same name as the initial picture?

This is the macro I wanted to use:

// @File(label = “Input directory”, style = “directory”) input
// @File(label = “Output directory”, style = “directory”) output
// @String(label = “File suffix”, value = “.tif”) suffix

/*

  • Macro to count nuclei in multiple images in a folder/subfolders.
    */

processFolder(input);

// function to scan folders/subfolders/files to find files with correct suffix
function processFolder(input) {
list = getFileList(input);
for (i = 0; i < list.length; i++) {
if(File.isDirectory(input + list[i]))
processFolder("" + input + list[i]);
if(endsWith(list[i], suffix))
processFile(input, output, list[i]);
}
//saves results for all images in a single file
saveAs(“Results”, output + “/All_Results.tsv”);
}

function processFile(input, output, file) {
run(“RGB Stack”);
setBatchMode(true); // prevents image windows from opening while the script is running
// open image using Bio-Formats
run(“Bio-Formats”, “open=[” + input + “/” + file +"] autoscale color_mode=Default rois_import=[ROI manager] view=Hyperstack stack_order=XYCZT");
id = getImageID(); // get original image id
run(“Duplicate…”, " "); // duplicate original image and work on the copy

// create binary image
setAutoThreshold("Default dark");
//run("Threshold...");
setThreshold(50, 255); // stellt meinen Threshold Wert ein
run("Create Mask");
run("Watershed");
// save current binary image
save(output + "/Binary_OUTPUT_" + file);
run("Analyze Particles...", "size=0.0001-Infinity exclude add"); // lässt die Partikel zählen
selectImage(id); // activate original image
roiManager("Show All with labels"); // overlay ROIs
roiManager("Deselect");
roiManager("Measure"); // measure on original image

// save ROIs for current image
roiManager("Deselect");
roiManager("Save", output+ "/" + file + "_ROI.zip"); // saves Rois zip file
roiManager("Deselect");
roiManager("Delete"); // clear ROI Manager for next image

}

Thanks!
Jan

Hi @Jay_N,

There are a couple of issues with the script you posted. Before pointing them out, I’d like to remind you that it is advisable to first lay out the complete problem in simple terms, and, if possible, provide sample images. It is difficult to debug a whole macro if the type of input or the intended results are not completely clear.

In particular, in your case I’m still unsure wether you are actually starting from RGB images (I suspect that’s not the case). Could you please confirm that, or provide a sample image?

That being said, let’s take a look a the code, which I reproduce again with formatting for ease of reading. In the future, please make sure you paste code as preformated text, using the button bar above:
imagen

// @File(label = "Input directory", style = "directory") input
// @File(label = "Output directory", style = "directory") output
// @String(label = "File suffix", value = ".tif") suffix

/*
Macro to count nuclei in multiple images in a folder/subfolders.
*/

processFolder(input);

// function to scan folders/subfolders/files to find files with correct suffix
function processFolder(input) {
	list = getFileList(input);
	for (i = 0; i < list.length; i++) {
		if(File.isDirectory(input + list[i]))
			processFolder("" + input + list[i]);
		if(endsWith(list[i], suffix))
			processFile(input, output, list[i]);
		}
	//saves results for all images in a single file
	saveAs("Results", output + "/All_Results.tsv");
	}

function processFile(input, output, file) {
	run("RGB Stack");
	setBatchMode(true); // prevents image windows from opening while the script is running
	// open image using Bio-Formats
	run("Bio-Formats", "open=[" + input + "/" + file +"] autoscale color_mode=Default rois_import=[ROI manager] view=Hyperstack stack_order=XYCZT");
	id = getImageID(); // get original image id
	run("Duplicate…", " "); // duplicate original image and work on the copy
	
	// create binary image
	setAutoThreshold("Default dark");
	//run("Threshold...");
	setThreshold(50, 255); // stellt meinen Threshold Wert ein
	run("Create Mask");
	run("Watershed");
	
	// save current binary image
	save(output + "/Binary_OUTPUT_" + file);
	run("Analyze Particles...", "size=0.0001-Infinity exclude add"); // lässt die Partikel zählen
	selectImage(id); // activate original image
	roiManager("Show All with labels"); // overlay ROIs
	roiManager("Deselect");
	roiManager("Measure"); // measure on original image
	
	// save ROIs for current image
	roiManager("Deselect");
	roiManager("Save", output+ "/" + file + "_ROI.zip"); // saves Rois zip file
	roiManager("Deselect");
	roiManager("Delete"); // clear ROI Manager for next image
	}

The issues that I see are:

These lines do not seem to belong here, inside the recursive function. If you want to save a single table with the results from all the images in the folder and subfolders, this code should go right after you call processFolders() in the main part of the script.

While this command does not seem to make sense (as mentioned early), it is at least misplaced: you can’t run it before opening the input image. But then again, if you open the images with Bio-Formats, you probably already have a multichannel image to start with.

In any case, if you have several channels, your code does not operate with them (no Stack.setChannel(), no run("Split Channels"), etc.).
Is it possible that you used the recorder to generate the code? In that case, be aware of the fact that it does not record when moving between channels in a multichannel image. So, all the switching back and forth between channels will be missing, and should be added manually after recording.

You are overriding the AutoThreshold (which is probably there after recording). You should clean up the code to reflect the actual command that you intend to use.

This command, which is ok by itself, might give you a false sense of “clean operation”, but will get you in trouble with memory usage if the function is called several times, as you are not closing any of the images you open/generate until the last comand of the script. It is a better practice to also keep tabs of the images you spawn in each round, and making sure you close all of them before proceeding to the next round. The laziest way to do it (if you are sure there are no images already open / you don’t care about them also closing) is running this at the end of the function:

close("*");

Also, my personal preference is using setBatchMode(true); at the begining of the script, so that it is called only once (and maybe explicitely calling setBatchMode(false); when this mode is no longer needed, which is useful when merging different scripts later on).

These lines assume there is at least one object detected. If that’s not the case, the script will fail.
You sould check beforehand:

// save ROIs for current image
if(roiManager("count") > 0) { // at least one ROI present
	roiManager("Deselect");
	roiManager("Save", output+ "/" + file + "_ROI.zip"); // saves Rois zip file
	roiManager("Deselect");
	roiManager("Delete"); // clear ROI Manager for next image
	}

It is quite possible that further changes to the macro will be required for it to perform as you expect, but with the information that I have available now, I cannot say that for sure.

Let me know if this helps you.

Cheers,
Nico