Can't make new subfolders

Hi guys,

I’m trying to batch process some tiff 4 channel stacks. I want to save the processed files in a new directory within another new directory.
So far I can only get it to crash asking for a numeric value in a File.separator or to process the images and not creating new directories nor saving.
Any help is apreciated.

//Prompts the user to choose a folder with the images.
dir1 = getDirectory("Choose Source Directory ");
//Prompts user to choose destination folder for saving post-analyzed images.
dir2 = getDirectory("Choose Destination Directory ");

list = getFileList(dir1);

for (i=0; i<list.length; i++) {

if (endsWith(list[i], ".tiff")) {
		showProgress(i+1, list.length);
	dir3 = (dir2+File.separator+list[i]);
		File.makeDirectory(dir3);
	dir4 = (dir3+File.separator+"I");
		File.makeDirectory(dir4);
		open(dir1+list[i]);

		//Image analysis macro:
		//run("Median 3D...", "xradius=1 yradius=1 zradius=1 add_stack");
		run("Split Channels");
		selectWindow("C1-"+list[i]);
		//getMinAndMax(min, max);
 		//run("Apply LUT", "add stack");
 		run("Enhance Contrast...", "saturated=0.03 normalized add_stack");
		saveAs(".tiff", dir4+"CtBP2");
		run("Close");
		selectWindow("C2-"+list[i]);
		run("Enhance Contrast...", "saturated=0.03 normalized add_stack");
		run("8-bit", "add stack");
		saveAs(".tiff", dir4+"PSD95");
		run("Close");
		selectWindow("C3-"+list[i]);
		run("Enhance Contrast...", "saturated=0.03 normalized add_stack");
		run("8-bit", "add stack");
		saveAs(".tiff", dir4+"Brn3a");
		run("Close");
		selectWindow("C4-"+list[i]);
		run("Enhance Contrast...", "saturated=0.03 normalized add_stack");
		run("8-bit", "add stack");
		saveAs(".tiff", dir4+"Topro");
		run("Close");
 		}
	}

Hi @sedonio,

To get a clear cut path, get the file name of the image, do a replace(string, old, new) of the file name in the whole path with an empty string. Thus you have a path with the file separator already in place.
If you need to look at the File.separator, you now can compare it with the last character of the path.

Add a new directory and add a file separator to get your dir3 path. Need code? Or are you familiar enough with the built in functions?

Long paths do not show up well in the Debug variable list. Print(dir1); will show up in the log and will be visible in its entirety.

Hi @eljonco,
Thanks for replying!
I may need code (I could certainly use a hand) as I can’t get this to work. After printing the paths, I see that I was getting 0 in dir3 and dir4.
Now I can get dir3 to print the path I need but it won’t create it. If i check with File.isDirectory(dir3) I get a true value but still won’t do it.I also don’t get why that replace is necessary but if I take it out it goes back to 0.
dir4 still crashes looking for a numeric value in the middle of file.separator but I’ll be more than happy to get one thing going, at least.
It now looks like this:

open(dir1+list[i]);
FileName=dir2+File.nameWithoutExtension;
replace(FileName, “”, “”)
dir3 = (FileName);
print(dir3);

Hi @sedonio,

The fact that it stops working if you take the replace out suggests that you do not create the proper string that represents the path in a way the system can create new folders. The zero indicates a ‘false’, so that means the path represented by the string isn’t pointing to a folder.

On what system are you ? it might be a permissions issue and in that case, it is a platform-dependent solution. Can you manually create that folder?
Do you use ImageJ1 or FIJI? This because of the next debugging steps I’d like to suggest.

Hi @eljionco,
This pc is from work so I don’t get to choose much.
It’s windows 10, I’m using Fiji - IMageJ1.52 java 1.8.0_172.
I can manually make folders. I even thought of making the folders on a different language and then sticking the images there but if I can’t get Fiji to recognize the paths I’m guessing I will run into similar problems.

Hi again,
I just came back to the macro.
It still reads (and doesn’t work):

open(dir1+list[i]);
FileName=dir2+File.nameWithoutExtension;
replace(FileName, “”, “”)
dir3 = (FileName);
File.isDirectory(dir3)
print(dir3);
File.makeDirectory(dir3);

That code prints: E:\Manuel\Lab\Fotos\SP8\PSD95 CTBP2 checked marks\Analysis\Stacks for macro to process hyperstacks.Tiff\666R_14dayLIOH_CtBP2-405_Brn3a-488_PSD95-568_TOPRO_2 and gets a true value from File.isDirectory but still won’t create the folder.
To see if it was a matter of Fiji not being able to create folders I googled for a macro that did that. I found this one from Martin Hoehne, August 2015.

// create folders for the tifs
dir1parent = File.getParent(dir1);
dir1name = File.getName(dir1);
dir2 = dir1parent+File.separator+dir1name+"–Tiff_MIP";
if (File.exists(dir2)==false) {
File.makeDirectory(dir2); // new directory for tiff
}

That works. It will create a folder on the parent directory from where the images are. Not what I am looking for as it doesn’t use the files names but now I know it’s not a general problem.

You havent < >'ted the path, so I guess the path name ends at \Stacks. In that case: there is a couple of spaces in your path. Just for testing: use a path that does not contain spaces. Does your macro work then?
If you need to have spaces in the path, what is the escape character? It is probably not , as that is your File.separator.
In your code you can drop the replace(FileName, “”, “”) line, as this adds (pun intended) nothing.
Finally, you first check if your code finds a (that dir3) directory, then you try to create exactly that dir3 folder. I think you meant to do something else.

Hi again and thanks for helping.
So, I’ve finally gotten the script to actually generate folders. However, I think I have unlearnt many things in order to get there
This code generates a folder based on the name of the file on a manually selected path.

/*This macros processes only tif files in a folder.
*/

//Prompts the user to choose a folder with the images.
dir1 = getDirectory("Choose Source Directory ");
//Prompts user to choose destination folder for saving post-analyzed images.
dir2 = getDirectory("Choose Destination Directory ");
//Numbers each file in dir1 and puts these numbers into a list. 
list = getFileList(dir1);

//Analyzes each image based on the number that each file has been assigned.
for (i=0; i<list.length; i++) {
//Following "if" statements creates condition for which files to process in the folder.
	if (endsWith(list[i], ".tiff")) {
		showProgress(i+1, list.length);
		open(dir1+list[i]);
		FileName=dir2+File.separator+File.nameWithoutExtension+File.separator;
		File.makeDirectory(FileName);
		//Image analysis macro:
		run("Median 3D...", "x=1 y=1 z=1");
		run("Split Channels");
		selectWindow("C1-"+list[i]);
		run("Enhance Contrast...", "saturated=0.3 normalize process_all use");
		run("8-bit", "add stack");
		saveAs(".tiff", FileName+"CtBP2");
 		run("Close");
		selectWindow("C2-"+list[i]);
		run("Enhance Contrast...", "saturated=0.3 normalize process_all use");
		run("8-bit", "add stack");
		saveAs(".tiff", FileName+"PSD95");
		run("Close");
		selectWindow("C3-"+list[i]);
		run("Enhance Contrast...", "saturated=0.3 normalize process_all use");
		run("8-bit", "add stack");
		saveAs(".tiff", FileName+"Brn3a");
		run("Close");
		selectWindow("C4-"+list[i]);
		run("Enhance Contrast...", "saturated=0.3 normalize process_all use");
		run("8-bit", "add stack");
		saveAs(".tiff", FileName+"Topro");
		run("Close");
 		}
	}

It’s not exactly what I want, I want the files to be in a folder named “I”, inside the folder named after the file.
I was able to generate that folder using the same line:

FileName=dir2+File.separator+File.nameWithoutExtension+File.separator+“I”+File.separator;
File.makeDirectory(FileName);

But, the code wouldn’t run if I did this after that

run(“Median 3D…”, “x=1 y=1 z=1”);

But it would if I commented it. Any thoughts? To me is a bit insane, truth be told.
Trying to get it to work now, maybe do a 2nd File.makeDirectory? Like so:

FileName=dir2+File.separator+File.nameWithoutExtension+File.separator;
File.makeDirectory(FileName);
FileName=FileName+File.separator+‘I’+File.separator;
File.makeDirectory(FileName);

That is working. Don’t really get how calling a a median 3d affects the folder making or why breaking File.makeDirectory in 2 steps solves the problem.
If you do, would really appreciate an explanation.
Anyways, it works now, I added batch mode and looks like this.

> 
> /*This macros processes only tif files in a folder.
> */
> 
> //Prompts the user to choose a folder with the images.
> dir1 = getDirectory("Choose Source Directory ");
> //Prompts user to choose destination folder for saving post-analyzed images.
> dir2 = getDirectory("Choose Destination Directory ");
> //Numbers each file in dir1 and puts these numbers into a list. 
> list = getFileList(dir1);
> setBatchMode(true)
> //Analyzes each image based on the number that each file has been assigned.
> for (i=0; i<list.length; i++) {
> //Following "if" statements creates condition for which files to process in the folder.
> 	if (endsWith(list[i], ".tiff")) {
> 		showProgress(i+1, list.length);
> 		open(dir1+list[i]);
> 		FileName=dir2+File.separator+File.nameWithoutExtension+File.separator;
> 		File.makeDirectory(FileName);
> 		FileName=FileName+File.separator+'I'+File.separator;
> 		File.makeDirectory(FileName);
> 		//Image analysis macro:
> 		run("Median 3D...", "x=1 y=1 z=1");
> 		run("Split Channels");
> 		selectWindow("C1-"+list[i]);
> 		run("Enhance Contrast...", "saturated=0.3 normalize process_all use");
> 		run("8-bit", "add stack");
> 		saveAs(".tiff", FileName+"CtBP2");
>  		run("Close");
> 		selectWindow("C2-"+list[i]);
> 		run("Enhance Contrast...", "saturated=0.3 normalize process_all use");
> 		run("8-bit", "add stack");
> 		saveAs(".tiff", FileName+"PSD95");
> 		run("Close");
> 		selectWindow("C3-"+list[i]);
> 		run("Enhance Contrast...", "saturated=0.3 normalize process_all use");
> 		run("8-bit", "add stack");
> 		saveAs(".tiff", FileName+"Brn3a");
> 		run("Close");
> 		selectWindow("C4-"+list[i]);
> 		run("Enhance Contrast...", "saturated=0.3 normalize process_all use");
> 		run("8-bit", "add stack");
> 		saveAs(".tiff", FileName+"Topro");
> 		run("Close");
>  		}
> 	}
> setBatchMode(false)

Hi @sedonio,

But, the code wouldn’t run if I did this after that

That is a bit meagre for an error message, I’m afraid.

I’d swap out the File.nameWithoutExtension for File.getNameWithoutExtension(path) as you know your path but do you know whatever happened in between now and the last time you opened a file? Maybe you opened a (text?) file in between. Then the ‘last opened file’ has changed and into the woods goes your macro.

Have a close look at the explanation of File. functions.

And do yourself -and us- a favour: use ; wherever proper, indent and use the </> in the editor, as that will give your code some colour and allows for copy/paste of code. Here is how that looks:

Indented macro
	//Prompts the user to choose a folder with the images.
dir1 = getDirectory("Choose Source Directory ");
	//Prompts user to choose destination folder for saving post-analyzed images.
dir2 = getDirectory("Choose Destination Directory ");
	//Numbers each file in dir1 and puts these numbers into a list.
list = getFileList(dir1);
setBatchMode(true);
	//Analyzes each image based on the number that each file has been assigned.
for (i=0; i<list.length; i++) {
	//Following "if" statements creates condition for which files to process in the folder.
	if (endsWith(list[i], ".tiff")) {
		showProgress(i+1, list.length);
		open(dir1+list[i]);
		FileName=dir2+File.separator+File.nameWithoutExtension+File.separator;
		File.makeDirectory(FileName);
		FileName=FileName+File.separator+‘I’+File.separator;
		File.makeDirectory(FileName);
		//Image analysis macro:
		run("Median 3D…", "x=1 y=1 z=1");
		run("Split Channels");
		selectWindow("C1-"+list[i]);
		run("Enhance Contrast…", "saturated=0.3 normalize process_all use");
		run("8-bit", "add stack");
		saveAs(".tiff", FileName+"CtBP2");
		run("Close");
		selectWindow("C2-"+list[i]);
		run("Enhance Contrast…", "saturated=0.3 normalize process_all use");
		run("8-bit", "add stack");
		saveAs(".tiff", FileName+"PSD95");
		run("Close");
		selectWindow("C3-"+list[i]);
		run("Enhance Contrast…", "saturated=0.3 normalize process_all use");
		run("8-bit", "add stack");
		saveAs(".tiff", FileName+"Brn3a");
		run("Close");
		selectWindow("C4-"+list[i]);
		run("Enhance Contrast…", "saturated=0.3 normalize process_all use");
		run("8-bit", "add stack");
		saveAs(".tiff", FileName+"Topro");
		run("Close");
	}
}
setBatchMode(false)

A final hint: use getImageID() and store the unique ID of an image; this is oftentimes safer than relying on the window name of the image once it is opened. Only exception: channels in a Merge. But then still, you can selectImage(imageID) followed by a getTitle().

1 Like