Issue with 'Find Peaks' plugin when used in a loop

macro
Tags: #<Tag:0x00007fb87de118c8>

#1

Dear ImageJ and FIJI community

I am trying to use the Find Peaks plugin (by Tiago Ferreira @tferr) in a macro, but I am having trouble to get it to run in a (time-) loop. In this macro, I am trying to move a lineROI (with user-defined length and width) in the centered over the brightest front of moving cells, where after I want to save the intensity profile of the line-ROI of 2 other channels in a table. The Macro actually works, but the issue seems to arise when I want to perform ‘plot profile’ within the same loop (please see macro: line 160-166 in macro). The crashes when I put these functions in the loop, but works when I out-comment lines 160-166.

I have traced down the issue to the ‘Find Peak’ plugin: I am using the X1-coodinate of the peak, which I am extracting from the window ‘plot values’ (which opens, but I am not selecting the window). However, to have the loop working, I need to close the ‘plot values’ window, but I am so far not able to select the window in the ImageJ macro language and close it. I read in the image-J forum that one can use the ‘auto-close’ (which I am trying in line 106 – for every loop), but also this does not seem to work for me. Is there any way to either close this window from the macro-language, or to extract the X1 –value?

To be complete, I have uploaded a draft of the macro here (as it is a bit long):

//Open image, set path and image-id
  //waitForUser("Please open image or image-stack");
  //run("Open...");

// image info
dir = getDirectory("image"); 
id = getTitle();
Stack.getDimensions(w, h, channels, slices, frames)
getVoxelSize(width, height, depth, unit)
setVoxelSize(1, 1, 1, "pixel") 								// temporal change of image depth

//---
selectWindow(id);
run("Duplicate...", "duplicate");
run("8-bit");
run("Red");
rename("imageRed");
run("Duplicate...", "duplicate");
run("Green");
rename("imageGreen");
run("Tile");
//---

// put ROI in roi manager
setTool("line");

roiManager("Add ALL YOUR ROIs");
roiManager("Associate", "true");
roiManager("Centered", "false");
roiManager("UseNames", "false");

waitForUser("Please add all line-ROIs" + "\n" 
			+ "to add to ROI manager press 't' " 
			+ "\n" + " " + "\n" 
			+ "! only click OK only when done");



// set desired line length and width
title = "Linesettings";
width=512; height=512;
Dialog.create("Choose desired line length and width");
Dialog.addSlider("Line Length", 1, 100, 10)
Dialog.addSlider("Line Width", 1, 100, 10)
Dialog.show();

desiredLength = Dialog.getNumber();							// Width from dialog
desiredLineWidth = Dialog.getNumber(); 						// Width from dialog


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////// *** resize  line ROI *** ////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 selectWindow("imageRed");

// 	loop ROIs
for (i=0 ; i<roiManager("count"); i++) {
roiManager("select", i);
roi = i + 1;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////// *** replace peak locations per timepoint *** ////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//-> roiManager("Select", 0);
//-> run("Select None");

// set loop for time (each ROI is analysed over all timepoints)
		for (q=1; q<frames; q++) { 
				Stack.getPosition(ch, sl, fr)		 // get current positions in image-stack (channel, slice and frame)			
				showProgress(q, frames); 
 
 ///	selectWindow("SKELETON-CH2");
	    selectWindow("imageRed");
//	    run("Select None");
    	roiManager("select", i);
		Stack.setFrame(q);
		run("Restore Selection");
//		roiManager("Update");
				
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// = presvious at line 58
///// Original line (#1)
roiManager("select", i);

getLine(x1, y1, x2, y2, lineWidth);					// line#1 - input from user
       dxLine1 = (x2-x1);
       dyLine1 = (y2-y1);
       angleLine1 = atan2(y2 - y1, x2 - x1);		// used to for calculation line #2 (see line74)

        length = sqrt(dxLine1*dxLine1 + dyLine1*dyLine1);
        scaleFactor = desiredLength/length;		
		//	xCenter = x1 + (dxLine1 / 2);				// must be same as angle line #2 (see line56)
		//	yCenter = y1 + (dyLine1 / 2);				// must be same as angle line #2 (see line56)
 
		///// Redraw ROI as lines with fixed length and width (line #2)
		dxScaled = dxLine1 *scaleFactor;
		dyScaled = dyLine1 *scaleFactor;

    
		// Find the peak on ROI -line (x-coordinate)
		setLineWidth(desiredLineWidth);
		run("Plot Profile");
		rename(id + "_line" + roi);  								// change name 
		Profile0 = getTitle;										// get the new name as variable 'Profile1'

		run("Plots...", "width=300 height=300 font=12 auto-close minimum=0 maximum=0");
		run("Find Peaks", "min._peak_amplitude=50 min._peak_distance=10 min._value=[] max._value=[] list");
		rename("Peaks in Plot of " + id + "_line" + roi); 			// change name 
		PeakPlot0 = getTitle;										// get the new name as variable 'Profile1'
		
		selectWindow("Plot Values");
		PeakPosition =getResult("X1", 0);
		//PeakY =getResult("Y1", 0); 								// intensity of the peak
 		close("Plot Values");										// close gaussian fit

 		waitForUser("plot Values close?");

// Determine coordinate of peak=> center of new line(#2) 
    	dxPeakPlot = PeakPosition *cos(angleLine1); 	            // determine dx from position of peak on lineplot 
    	dyPeakPlot = PeakPosition *sin(angleLine1);	    	         // determine dy from position of peak on lineplot
    
// Determine coordinate of peak in image => center of new line(#2) 
    	xPeak = (x1+dxPeakPlot);									// xPeak is the position of the peak in the image and should be the center of the new line
    	yPeak = (y1+dyPeakPlot);									// yPeak is the position of the peak in the image and should be the center of the new line

// Set new coordinaes of line with fixed length and width in image (line #2)
    	x3 = xPeak - dxScaled;
    	y3 = yPeak - dyScaled;
    	x4 = xPeak + dxScaled;
    	y4 = yPeak + dyScaled;
                
		//selectImage(id);
		selectWindow("imageRed");
		Stack.setFrame(q);
		makeLine(x3, y3, x4, y4, desiredLineWidth); // make line #3 on center of peak
		roiManager("Update");
		// run("Restore Selection");

		//selectImage(id);
		selectWindow("imageRed");
		run("Select None");

 		// close plots
		close(Profile0);									// close profile plot
		close(PeakPlot0);									// close gaussian fit
 		//close("Plot Values");								// close gaussian fit

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	    	
/////Get Intensity profile from ROI(i) on "Z-stack_CH1peaks" and add to table		
				selectWindow("imageGreen");
				roiManager("select", i);
				Stack.setFrame(q);
//		    	run("Restore Selection");					 
//		    	Roi.setStrokeWidth(desiredLineWidth);		

/////Get profile from ROI(i) on Z-stack_CH1peaks" and add to table	
//->				selectWindow("Z-stack_CH1peaks");
  				profile = getProfile();
	  			for (j=0; j<profile.length; j++) 							// j = data-point index
	      		setResult("CH1"+ "_ROI" +roi + "_T" + q, j, profile[j]);
	  			updateResults;
	  					
//				selectWindow("Z-stack_CH1peaks");
				run("Select None");

				
/////Get Intensity profile from ROI(i) on "Z-stack_CH2peaks" and to table
//		        selectWindow("Z-stack_CH1peaks");
//		        roiManager("select", i);		
//				Stack.setFrame(q);
//		    	run("Restore Selection");
//		    	Roi.setStrokeWidth(desiredLineWidth);		
				
/////Get profile from ROI(i) on "Z-stack_CH2peaks" and add to table	
//->				selectWindow("Z-stack_CH2peaks");
//->  				roiManager("select", i);
//->  				run("Restore Selection");
//->  				profile = getProfile();
//->	  			for (j=0; j<profile.length; j++) 							// j = data-point index
//->	      		setResult("CH2"+ "_ROI" +roi + "_T" + q, j, profile[j]);
//->	  			updateResults;

				//selectWindow("Z-stack_CH2peaks");
				//run("Select None");

//->				selectWindow("MASK-CH2");
				
//				roiManager("select", i);
				/// Stack.setFrame(t);					// Displays frame 't' . 
				/// roiManager("Update"); 				// run("Restore Selection");
	
} // end of Time loop

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

} // end of ROI loop

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Save all results in xls-file, with similar as original image 'id'
// selectWindow("Gauss Fits");		 				 	//selectWindow("Gauss Fits");
// saveAs("Measurements" dir + id + "_ALL" + ".xls");   	//selectWindow("Gauss Fits");
  saveAs("Results", dir + id + "ALL.xls");
  run("Close"); 

  

// set back image porperties as obtained in line 9
setVoxelSize(width, height, depth, unit) 			
// selectWindow("Plot Values");
        
selectWindow("DUPLICATE");
close();

I put a sample image here: https://seafile.ist.ac.at/f/ddde01c3d0/
(please draw a lineROI over the white line)

I am using FIJI with ImageJ 1.51k (last update – also from BAR plug-in site) on a Windows 7 (64bit) machine (and tried Mac OS 10.12.4 as well).

Many thanks in advance for any tips you can share!
With kind regards,

Gabriel


#2

Dear Gabriel,

A couple of things:

  • the close() function only applies to images, that’s why is not working for you. From the documentation:

close()
Closes the active image. This function has the advantage of not closing the “Log” or “Results” window when you meant to close the active image. Use run(“Close”) to close non-image windows.

  • Your macro is extremely long and hard to debug. Please consider splitting into blocks so that a task is executed in a self-contained function. E.g., you could replace your close() calls with your own close function that works with any ImageJ window:
 function closeAnyWindow(title) {
	// this functions closes both image- and non-image windows
	if (isOpen(title)) {
		selectWindow(title);
		run("Close");
	} else {
		print("Window '"+ title +"' not found");
	}
}

closeAnyWindow("Plot Values");
  • I think your problem is not related to Find Peaks. It is rather that, for some reason,
    getProfile() is returning an empty array when you call profile = getProfile();. You can test this by including a debug line before your for {} loop:
profile = getProfile();
if (profile.length == 0) {
	print("An exception is about to be thrown in the upcoming for loop");
	// handle it here
}
for (j=0; j<profile.length; j++) {
	// (...)
}
  • Also, your macro overrides user preferences (e.g., it changes the default settings for new plots) without user permission which is rather impolite. Please use saveSettings() at the beginning and restoreSettings at the end of your macro to avoid overriding user preferences.

  • In cases like this, it is always better to provide a minimal, verifiable example


#3

Dear Tiago,

Thank you so much for your feedback and the useful (general) tips too!
I will give it a try and hope that I manage to get things working again: I have something to work on - thanks!

best regards,
Gabriel