Fiji - ImageJ: Order of batch processing ?!

Hi everbody, I struggle with following problem with FIJI / IMAGEJ.

I have created two macros, one which produces a list of file names that lay in a selected folder:

 dir = getDirectory("Choose a Directory ");
  count = 1;
  listFiles(dir); 

  function listFiles(dir) {
     list = getFileList(dir);
     for (i=0; i<list.length; i++) {
        if (endsWith(list[i], "/"))
           listFiles(""+dir+list[i]);
        else
           print((count++) + ": " + list[i]);
     }
  };

That is working totally fine. Than, I have another macro code, with the Function “Find maxima”, that is counting cells after splitting a RGB picture. The results (number of cells) is presented in the usual results table.

originalTitle = getTitle(); 
run("Split Channels");
selectWindow(originalTitle + " (blue)");
run("Close"); 

////green channel////
selectWindow(originalTitle + " (green)"); 
run("8-bit");
run("Find Maxima...", "prominence=32 strict exclude output=Count");
selectWindow(originalTitle + " (green)");
run("Close"); 

But: When I run the counting macro in a batch process of many files, the results won’t appear in the order of the files on my pc. Is seems like there isn’t any logical running order (alphabetic, size, …) at all …

Does anyone know something about that? Is there a certain order in which Fiji executes the batch process? Otherwise I wouldn’t be able to assign the results to the different files …

Thank you!

Hi @Haschkez_S
I’m not sure why your files are not sorted when batch processing. However, you can check Display label within the Analyze>Set Measurements... dialog window.

For the macro script:

run("Set Measurements...", "display redirect=None decimal=3")

In this way you should obtain a results table containing an additional column storing the name of each file
Best

2 Likes

Hi
@Haschkez_S
A discussion on the batch processing order:

Maybe that will give you a working track.
Greetings

@Haschkez_S

You should be able to consolidate your macros into a single one… you can use the template provided in the Script Editor - it’s called Process Folder (IJ1 Macro) (Templates > ImageJ1.x > Batch > Process Folder (IJ1 Macro)):

/*
 * Macro template to process multiple images in a folder
 */

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

// See also Process_Folder.py for a version of this code
// in the Python scripting language.

processFolder(input);

// function to scan folders/subfolders/files to find files with correct suffix
function processFolder(input) {
	list = getFileList(input);
	list = Array.sort(list);
	for (i = 0; i < list.length; i++) {
		if(File.isDirectory(input + File.separator + list[i]))
			processFolder(input + File.separator + list[i]);
		if(endsWith(list[i], suffix))
			processFile(input, output, list[i]);
	}
}

function processFile(input, output, file) {
	// Do the processing here by adding your own code.
	// Leave the print statements until things work, then remove them.
	print("Processing: " + input + File.separator + file);
	print("Saving to: " + output);
}

You can modify it to process each file/image in folder/subfolders at a time and save the results as you go… so something like this:

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

processFolder(input);

// function to scan folders/subfolders/files to find files with correct suffix
function processFolder(input) {
	list = getFileList(input);
	list = Array.sort(list);
	for (i = 0; i < list.length; i++) {
		if(File.isDirectory(input + File.separator + list[i]))
			processFolder(input + File.separator + list[i]);
		if(endsWith(list[i], suffix))
			processFile(input, output, list[i]);
	}
}

function processFile(input, output, image) {
	run("Bio-Formats", "open=[" + input + File.separator + image +"] autoscale color_mode=Default rois_import=[ROI manager] view=Hyperstack stack_order=XYCZT");
  	originalTitle = getTitle(); // get original image title

	run("Split Channels");
	////green channel////
	selectWindow(originalTitle + " (green)"); 
	run("8-bit");
	run("Find Maxima...", "prominence=32 strict exclude output=Count");
	roiManager("Add");
	roiManager("Measure");
	// save results for current image
	saveAs("Results", output + File.separator + originalTitle + "-Results.csv"); 
	roiManager("Delete"); // clear ROI Manager for next image
	selectWindow("Results"); 
	run("Close");
	run("Close All");
}

Note: you may need to modify this code… depending on how you want to save things, etc. Hope it’s a good start though!

1 Like

Hey @etadobson
Thank you very much for your detailed answer !!!

I tried the following code: But every time I get the error “The active image does not have a selection”. I am quiet new to ImageJ and have no idea what could be wrong …

/*
 * Macro template to process multiple images in a folder
 */

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


processFolder(input);

// function to scan folders/subfolders/files to find files with correct suffix
function processFolder(input) {
	list = getFileList(input);
	list = Array.sort(list);
	for (i = 0; i < list.length; i++) {
		if(File.isDirectory(input + File.separator + list[i]))
			processFolder(input + File.separator + list[i]);
		if(endsWith(list[i], suffix))
			processFile(input, output, list[i]);
	}
}

function processFile(input, output, image) {
	run("Bio-Formats", "open=[" + input + File.separator + image +"] autoscale color_mode=Default rois_import=[ROI manager] view=Hyperstack stack_order=XYCZT");
  	originalTitle = getTitle(); // get original image title

	run("Split Channels");
	selectWindow("C3-" + originalTitle); 
	run("Close");
	selectWindow("C1-" + originalTitle); 
	run("Close"); 


////green channel////
	selectWindow("C2-" + originalTitle); 
	run("8-bit");
	run("Find Maxima...", "prominence=32 strict exclude output=Count");
	roiManager("Add");
	roiManager("Measure");
	
	// save results for current image
	saveAs("Results", output + File.separator + originalTitle + "-Results.csv"); 
	roiManager("Delete"); // clear ROI Manager for next image
	selectWindow("Results"); 
	run("Close");
	run("Close All");


	

}

Hi @pau
Thank you for your answer! That would be a solution for me, if there isn’t another possibility to get the results directly in the right order. Thanks!

@Haschkez_S

No worries! It might be that no maxima are found on certain images… which is why you see this ‘error’ being reported… do all of your images have points found with this function call? Or is it the case that certain images have no points?

I checked that right know manually: All of my pictures in that specific folder have points that could be found …

Ok. @Haschkez_S then can you upload an original image that I can use to run this - to test?

Too - does the error occur immediately? ie - are any results tables saved when you run this?

Actually one result is saved. Yes of course, I uploaded the five files I’ve been testing the macro with. Thank you for your help!

If it is too complicated I think I could go on with @pau 's solution.

@Haschkez_S

I see the problem… It was the settings you were using on the Find Maxima call… just having the count printed out.

This should work:


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


processFolder(input);

// function to scan folders/subfolders/files to find files with correct suffix
function processFolder(input) {
	list = getFileList(input);
	list = Array.sort(list);
	for (i = 0; i < list.length; i++) {
		if(File.isDirectory(input + File.separator + list[i]))
			processFolder(input + File.separator + list[i]);
		if(endsWith(list[i], suffix))
			processFile(input, output, list[i]);
	}
}

function processFile(input, output, image) {
	run("Bio-Formats", "open=[" + input + File.separator + image +"] autoscale color_mode=Default rois_import=[ROI manager] view=Hyperstack stack_order=XYCZT");
  	originalTitle = getTitle(); // get original image title

	run("Split Channels");

////green channel////
	selectWindow("C2-" + originalTitle); 
	run("Find Maxima...", "prominence=32 strict exclude output=Count");
	// save results for current image
	saveAs("Results", output + File.separator + originalTitle + "-Results.csv"); 
	selectWindow("Results"); 
	run("Close");
	run("Close All");	
}

But it might be easier to also incorporate what @pau mentioned as well - and then only save a single results table at the end - like this:


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

run("Set Measurements...", "display redirect=None decimal=3");
processFolder(input);

// function to scan folders/subfolders/files to find files with correct suffix
function processFolder(input) {
	list = getFileList(input);
	list = Array.sort(list);
	for (i = 0; i < list.length; i++) {
		if(File.isDirectory(input + File.separator + list[i]))
			processFolder(input + File.separator + list[i]);
		if(endsWith(list[i], suffix))
			processFile(input, output, list[i]);
	}
	// save results for all images
	saveAs("Results", output + File.separator + "All-Results.csv"); 
}

function processFile(input, output, image) {
	run("Bio-Formats", "open=[" + input + File.separator + image +"] autoscale color_mode=Default rois_import=[ROI manager] view=Hyperstack stack_order=XYCZT");
  	originalTitle = getTitle(); // get original image title

	run("Split Channels");

////green channel////
	selectWindow("C2-" + originalTitle); 
	run("Find Maxima...", "prominence=32 strict exclude output=Count");
	// save results for current image
	run("Close All");	
}

:slight_smile:

1 Like

Perfect, thank you all! :blush:

2 Likes