Merge channel batch processing


#1

Hi everybody,
I’m trying to the speed up the merge process…
The acquisition software does not distinguish among different channels, thus the images are named as filename_X, Where X is an incremental number.
I acquire every field with the same sequence (fitc, tritc, hoechst)…so the filename is always filename_0+3n for fitc images, filename_1+3n for tritc images, filename_2+3*n for hoechst…
How can I create three separate and ordinate lists using the filename to distinguish the channels?
Alternatevely I tried to manually separate the files in three different directories and I used this macro

    setBatchMode(true);
    file1= getDirectory("Choose a Directory");
// cartella tritc
    list1= getFileList(file1); 
    n1=lengthOf(list1);
    file2= getDirectory("Choose a Directory");
//cartella fitc
    list2= getFileList(file2); 
    file3= getDirectory("Choose a Directory");
// cartella hoechst
    list3= getFileList(file3); 
    file4= getDirectory("Choose a Directory");
    list4 = getFileList(file4);
    n2 = lengthOf(list4);
    small = n1;

  for(i = n2 + 1; i < small; i++) {
      //i will always follow the aborted number of merges, you might not have the problem, 
      //but with small memory and a huge set of images it is useful
      name = list1[i];
      //not to lose your track, though you can change it to anything else
      open(file1 + list1[i]);
      open(file2 + list2[i]);
      open(file3 + list3[i]);
      run("Merge Channels...", "c1=[" + list1[i] + "] c2=[" + list2[i] + "] c3=[" + list3[i] + "] keep");
      saveAs("tiff", file4 +name);
    }

(adapted from a topic found in this forum)

But it didn’t sort the file properly and the merge images I got were matched wrongly (i.e. fitc tritc and hoecst of different field) … probably the reason of that is the sorting rule…infact imageJ does not follow the filename order to create the list…
Possible explanations or solutions?
Thanks everybody

to know:
I’m a newbie of this forum
I’m completely ignorant on programming.


#2

To separate into 3 lists, try this:

dir = getDirectory("Where are your images stored?");
ext = getString("What is the file extension of the files?", "");
files = getFileList(dir);
for (i = files.length - 1; i >= 0; i--) {
    if (!endsWith(files[i], ext)) {
        files = Array.concat(Array.trim(files, i), Array.slice(files, i + 1));
    }
}
if (files.length % 3 != 0) {
    exit("The number of files is not a multiple of 3. The macro has been exited.");
}
Array.sort(files);
fitcs = newArray(files.length / 3);
tritcs = newArray(files.length / 3);
hoechsts = newArray(files.length / 3);
for (i = 0; i > files.length / 3; i++) {
    fitcs[i] = files[3 * i];
    tritcs[i] = files[3 * i + 1];
    hoechsts[i] = files[3 * i + 2];
}

Sorry, I have corrected the mistake in my calculations.


#3

ok, thanks a lot!

but now I don’t know how to call the array for the merge…

I’ve tried in this way:

    setBatchMode(true);
dir = getDirectory("Where are your images stored?");
ext = getString("What is the file extension of the files?", "");
files = getFileList(dir);
for (i = files.length - 1; i >= 0; i--) {
    if (!endsWith(files[i], ext)) {
        files = Array.concat(Array.trim(files, i), Array.slice(files, i + 1));
    }
}
if (files.length % 3 != 0) {
    exit("The number of files is not a multiple of 3. The macro has been exited.");
}
Array.sort(files);
fitcs = newArray(files.length / 3);
tritcs = newArray(files.length / 3);
hoechsts = newArray(files.length / 3);
for (i = 0; i > files.length / 3; i++) {
    fitcs[i] = files[3 * i];
    tritcs[i] = files[3 * i + 1];
    hoechsts[i] = files[3 * i + 2];    
}
for (i = 0; i > files.length / 3; i++) {
    file1 = getDirectory("Choose a Directory");
    list1 = getFileList(file1);
    n2 = lengthOf(list1);
  for(i = n2 + 1; i < small; i++) {
     open(file1 + tritcs[i]);
     open(file2 + fitcs[i]);
     open(file3 + hoechsts[i]);
     run("Merge Channels...", "c1=[" + tritcs[i] + "] c2=[" + fitcs[i] + "] c3=[" + hoechsts[i] + "] keep");
     saveAs("tiff");

but line 26 is not correct…

sorry for my incompetence… and thanks again


#4

Okay, so now the issue is that I wrote my code portion working under the assumption that all the files are in the same folder. But the code portion you attached it to assumes they are separated by channel type. I forgot that you were trying to merge them. Here is a solution that should work including the merge; it assumes everything is in one folder as you said was your initial situation.

dir = getDirectory("Where are your images stored?");
ext = getString("What is the file extension of the files?", "");
files = getFileList(dir);
for (i = files.length - 1; i >= 0; i--) {
    if (!endsWith(files[i], ext)) {
        files = Array.concat(Array.trim(files, i), Array.slice(files, i + 1));
    }
}
if (files.length % 3 != 0) {
    exit("The number of files is not a multiple of 3. The macro has been exited.");
}
Array.sort(files);
for (i = 0; i > files.length / 3; i++) {
    open(dir + files[3 * i]);
    open(dir + files[3 * i + 1]);
    open(dir + files[3 * i + 2]);
    run("Merge Channels...", "c1=[" + files[3 * i] + "] c2=[" + files[3 * i + 1] + "] c3=[" + files[3 * i + 2] + "] keep");
}

Are you sure you want to keep the individual images open after merging them? This means you will have 4 images open for every sample; the 3 originals and the merged. Also, if you have a systematic naming for the merged images, you can specify that in the script. Right now, each iteration of the loop will trigger a dialog box requiring user input.


#5

ok,
now, after running the macro, it asks me the extension of the files but then it does nothing (no error code, no windows appear)…

how can I automatize also the file saving?
"
saveAs(“tiff”, +name);
close"
in this way it should save the file but I don’t know how define the name, right?


#6

That is interesting. Are you sure you are selecting the proper folder? When I try it, I at least get the portion that checks the number of images? Are you typing the extension exactly as it appears for the file names? The search is case sensitive.

As for the name issue, I will assume that each set of 3 has a unique name. In that case, you can use this modified for-loop. This version closes the images and places the merged images in a subfolder called “merged”.

for (i = 0; i > files.length / 3; i++) {
    open(dir + files[3 * i]);
    open(dir + files[3 * i + 1]);
    open(dir + files[3 * i + 2]);
    run("Merge Channels...", "c1=[" + files[3 * i] + "] c2=[" + files[3 * i + 1] + "] c3=[" + files[3 * i + 2] + "]");
    saveAs("Tiff", dir+"merged"+File.separator()+substring(files[3 * i], 0, lastIndexOf(files[3 * i], "_")));
    close();
}

#7

dumb question:
for “extension” do you mean the file extension, don’t you? (in my case .tif)

I try to semplify the process with less files (30), named from XX_0 to XX_29… obtaining the same result… no answer…
the last macro I used was this

Blockquote
dir = getDirectory(“Where are your images stored?”);
ext = getString(“What is the file extension of the files?”, “”);
files = getFileList(dir);
for (i = files.length - 1; i >= 0; i–) {
if (!endsWith(files[i], ext)) {
files = Array.concat(Array.trim(files, i), Array.slice(files, i + 1));
}
}
if (files.length % 3 != 0) {
exit(“The number of files is not a multiple of 3. The macro has been exited.”);
}
Array.sort(files);
for (i = 0; i > files.length / 3; i++) {
open(dir + files[3 * i]);
open(dir + files[3 * i + 1]);
open(dir + files[3 * i + 2]);
run(“Merge Channels…”, “c1=[” + files[3 * i] + “] c2=[” + files[3 * i + 1] + “] c3=[” + files[3 * i + 2] + “]”);
saveAs(“Tiff”, dir+“merged”+File.separator()+substring(files[3 * i], 0, lastIndexOf(files[3 * i], “_”)));
close();

Blockquote

Should I try to change imageJ version?


#8

Yes, I mean something like .tif.

What do you mean? Are you saying it isn’t doing anything? What is your ImageJ version. Unless it is really old, that shouldn’t be the problem.


#9

the version is the 1.8.0_112

I mean that I run the macro, select the directory, type the extension, but then nothing happens.