Copying entire columns into new files Fiji Macro

Hey everyone,

There have been several discussions about how to copy entire rows.
However, I can’t find information on how to copy entire columns into a new file, while creating a new row per image using Fiji Macro language.

I have results data "path + “M_” + shortTitle + “measure.csv” (whereas shortTitle = unique to my images; the results file comes from 3D ROI Manager “Measure” - so we are talking about 20 objects/columns per file)
for all files in my folder I would like to extract the entire row “CX (pix)” and write the entire column into a new file; and then create a new row for each image
At the end I would like have a CXpix file which has all the X-position values for the images of the selected folder AND repeat this for a few other parameters (e.g. vol, elongation, etc), instead of having to open results files for each image.

        run("Clear Results");
	open(path + "M_" + shortTitle + "measure.csv");
	MeasX = newArray(nResults());
  
	for (i=0;i<nResults();i++){
		MeasX[i] =  getResult("CX (pix)", i);
		print(MeasX[i]); 
	}
        // here I would like to print it into the CXpix-file, with a new column per image
        // repeat for different variables

I know it should be trivial, but I reached the point of confusing myself…

Thanks in advance :slight_smile:

1 Like

Hi @EKugler welcome to the forum!

It would be really helpful if you could share an example input csv as it’s not immediately clear what you’re starting with.

My understanding from the plugin website is that CX (unit) would be a column, not a row. Do you mean “…extract the entire column “CX (pix)”…” ?

Regardless, I’m going to take a stab at this and perhaps some of this will be helpful. When I’m importing CSV files, I don’t tend to open them to the results table and instead read them in as a variable then just handle the data as delimited strings. Something like this in macro language:

#@ File (label = "Input file") inFile

//-- Read in the file as a string
fileData=File.openAsString(inFile);
//-- Split the whole thing into lines
fileData_lines=split(fileData, "\n");

//-- count how many lines we have and create a new array to hold one columns worth of values
numLines=fileData_lines.length
outputArray=newArray(numLines);

//-- loop through each line
for (i = 0; i < numLines; i++) {

//-- For each line, split it using the comma delimiter
	fileData_columns=split(fileData_lines[i],",");
//-- Store the third column into the outputArray
	outputArray[i]=fileData_columns[2];
}

//-- Sanity check
Array.print(outputArray);

You can make a simple CSV file to test this and it seems to work:

I posted recently to a question about saving variables out to CSV files so you can check that one regarding writing out the data again.

Apologies if that misses the mark completely. Hope it helps thought!

1 Like

Hey @dnmason,

Thanks so much for your help! I am definitely closer to the solution :slight_smile:

Reading the columns (I always mix up columns and rows, apologies!) as delimited strings, instead of as results, is very smart! I will do that in the future.

I added that it iterates over multiple files (which start with “M_”) and extraction of additional arrays.
Now tinkering around with how to best save the different arrays - see comments below.
Trying “print” it doesn’t tab delimit the arrays from different images, but writes them underneath.

These are 2 minimum-example files; I expect the actual data to be about 2-3 times the number of objects, but the extracted measurements will be the same.

Thanks again for your help. It’s really appreciated!

M_1measure.csv (2.8 KB) M_2measure.csv (22.3 KB)

MeasurePath = getDirectory("Input Folder");
filelistMeasure = getFileList(MeasurePath);

fileX = File.open(MeasurePath + "output.txt"); // display file open dialog

for (i=0; i< filelistMeasure.length; i++) {
	// select specific files using naming condition
	if (startsWith(filelistMeasure[i], "M_")) {
		//-- Read in the file as a string
		fileData=File.openAsString(MeasurePath + filelistMeasure[i]);
				
		//-- Split the whole thing into lines
		fileData_lines=split(fileData, "\n");
				
		//-- count how many lines we have and create a new array to hold one columns worth of values
		numLines=fileData_lines.length;
		ArrayCXum=newArray(numLines);
		ArrayCYum=newArray(numLines);
		ArrayCZum=newArray(numLines);
		
		//-- loop through each line
		for (k = 0; k < numLines; k++) {
		//-- For each line, split it using the comma delimiter
			fileData_columns=split(fileData_lines[k],",");
		//-- Store the third column into the outputArray
			ArrayCXum[k]=fileData_columns[8];
			ArrayCYum[k]=fileData_columns[9];
			ArrayCZum[k]=fileData_columns[10];

			// this would be alright, but it writes arrays underneath
			print(fileX, ArrayCXum[k] + " \t");
		}

// this one works for individiual arrays; but not multiple arrays
/*		Array.print(ArrayCXum);
		saveAs("Text",  MeasurePath + "ArrayCXum.txt"); // copy > Paste Transpose

		// tried to see if closing the log would work - but it doesn't
		//	close("Log");
		Array.print(ArrayCYum);
*/
	}
}

Thanks for some test data. Just so I’m understanding @EKugler, do you want a single output file to be one column of “CY (unit)” data per input “M_” file (presumably with 3 output files one for each of X,Y and Z), or are you trying to horizontally concatenate X,Y and Z data into one output file with “M_” files results vertically concatenated (so one column each for “CX (unit)”,“CY (unit)”,“CZ (unit)”).

A minimum output file might be helpful :slight_smile:

Hey @dnmason,

The idea would be to have separate output files for X,Y,Z; each with columns for the different M_'s (see screenshot) below.

Mainly I would like to being able to copy the object data (eg X,Y,Z) for the experimental groups more easily, than having to open each file and copying individual columns.

The column name (i.e. 1,2 etc) is just to show what I mean.

I hope that makes sense? :slight_smile:
image

It does, perfectly. I now see the problem you’re having, chiefly as a function of ImageJ arrays not being 2D.

The best way I can think of to handle the variable length of the columns is to dump the values into the results table, one column for each file, then you can save the whole thing out. A simple version (just using ArrayCXum is linked here (the forum sometimes messes up code, thus the repo link):

The nice (?) thing is that the results table will zero-fill any empty cells which may have just provided you with another problem to solve downstream (sorry!). Regardless you will end up with something like this:

To expand this to deal with all three values, you should probably rename the results table for each of X,Y,Z then you can save them all out at the end as separate files.

Good luck bringing it all together!

1 Like

Apologies for the delay! I will probably go for this last option, yes.
However, I will try replacing the 0 values for further analysis :slight_smile:

Hopefully I will have time next week and can share the full workflow in case someone has a similar issue.

Thanks again :slight_smile: