I need to rename hundreds of files in nested folders and using the model of the macro at https://imagej.nih.gov/ij/macros/ListFilesRecursively.txt , have generated code that does what we need.
I am confused by one issue, however, that c keeps incrementing. In our implementation (below), c is defined in a macro and is not passed to the function. c is not a global variable. When the function calls itself, it does not pass c. I thought the function would expect that either c had to be passed to it or would require a new instance to be defined before it could be incremented. Is this something I have been overlooking for years while diligently writing my code to pass all values needed by a function? Best regards- Michael macro "replace parts of file names recursively" { dir = getDirectory("Choose a Directory "); count = 1; listFiles(dir); } function listFiles(path) { list = getFileList(path); for (i=0; i<list.length; i++) { if (endsWith(list[i], "/")) listFiles(""+path+list[i]); else { path1 = path + list[i]; title_stripped = list[i]; // leave the tif extension on // clean up other likely issues in title title_stripped = replace(title_stripped, "-MaxIP", "max"); title_stripped = replace(title_stripped, "- C=0", ""); title_stripped = replace(title_stripped, "gamma", "gam"); path2 = path + title_stripped; ok = File.rename(path1, path2); // ok = 1 if successful print((count++) + ": " + path + list[i]); } } } Michael Cammer, Sr Research Scientist, DART Microscopy Laboratory NYU Langone Health, 540 First Avenue, SK2 Microscopy Suite, New York, NY 10016 Office: 646-501-0567 Cell: 914-309-3270 [hidden email]<mailto:[hidden email]> http://nyulmc.org/micros http://microscopynotes.com/ Acknowledgement in your publications and presentations of work performed in the Microscopy Core plays a vital role in securing support and the funding necessary to maintain and operate this valuable research resource. For publications that were made possible by work performed in the core, please use the acknowledgement statement "We thank the NYU Langone Microscopy Core for experimental and technical support" and include required grant numbers as listed here http://microscopynotes.com/ilabnyu/acknowledgements2017.pdf Please also consider staff for co-authorship if they played a key role in the study. ------------------------------------------------------------ This email message, including any attachments, is for the sole use of the intended recipient(s) and may contain information that is proprietary, confidential, and exempt from disclosure under applicable law. Any unauthorized review, use, disclosure, or distribution is prohibited. If you have received this email in error please notify the sender by return email and delete the original message. Please note, the recipient should check this email and any attachments for the presence of viruses. The organization accepts no liability for any damage caused by any virus transmitted by this email. ================================= -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Greetings Michael,
There is more than one variable called 'c'. Each scope, roughly between squiggly brackets (at least in the C/C++ derived languages), has its own context containing a symbol table with variable / value pairs. From the output of the attached macro it seems as though the called function's context is initialized by the context of its caller. Although, it does not seem to copy the values back to the calling context, which which can create nasty headaches. Each invocation of a scope seems to reuse its context and thus the increment performs as shown. Fred macro "UGH" { c = 10; prefun(); for(i=0; i<5; i++) fun(); fun() } function prefun() { c=100; print("C="+c); prefun2(); } function prefun2() { print("C = "+c); c=1000; print("C="+c); } function fun() { print("c="+c++); } output... C=100 C = 100 C=1000 c=10 c=11 c=12 c=13 c=14 c=15 On Thu, January 7, 2021 3:14 pm, Cammer, Michael wrote: > I need to rename hundreds of files in nested folders and using the model > of the macro at https://imagej.nih.gov/ij/macros/ListFilesRecursively.txt > , have generated code that does what we need. > > I am confused by one issue, however, that c keeps incrementing. > > In our implementation (below), c is defined in a macro and is not passed > to the function. c is not a global variable. When the function calls > itself, it does not pass c. > > I thought the function would expect that either c had to be passed to it > or would require a new instance to be defined before it could be > incremented. > > Is this something I have been overlooking for years while diligently > writing my code to pass all values needed by a function? > > Best regards- > Michael > > > macro "replace parts of file names recursively" { > dir = getDirectory("Choose a Directory "); > count = 1; > listFiles(dir); > } > > function listFiles(path) { > list = getFileList(path); > for (i=0; i<list.length; i++) { > if (endsWith(list[i], "/")) > listFiles(""+path+list[i]); > else > { > path1 = path + list[i]; > title_stripped = list[i]; // leave the > tif extension on > // clean up other likely > issues in title > title_stripped = > replace(title_stripped, > "-MaxIP", "max"); > title_stripped = > replace(title_stripped, "- > C=0", ""); > title_stripped = > replace(title_stripped, > "gamma", "gam"); > path2 = path + > title_stripped; > ok = File.rename(path1, > path2); // > ok = 1 if successful > print((count++) + ": " + > path + list[i]); > } > > } > } > > > > > Michael Cammer, Sr Research Scientist, DART Microscopy Laboratory > NYU Langone Health, 540 First Avenue, SK2 Microscopy Suite, New York, NY > 10016 > Office: 646-501-0567 Cell: 914-309-3270 > [hidden email]<mailto:[hidden email]> > http://nyulmc.org/micros http://microscopynotes.com/ > Acknowledgement in your publications and presentations of work performed > in the Microscopy Core plays a vital role in securing support and the > funding necessary to maintain and operate this valuable research resource. > For publications that were made possible by work performed in the core, > please use the acknowledgement statement "We thank the NYU Langone > Microscopy Core for experimental and technical support" and include > required grant numbers as listed here > http://microscopynotes.com/ilabnyu/acknowledgements2017.pdf > Please also consider staff for co-authorship if they played a key role in > the study. > > > > ------------------------------------------------------------ > This email message, including any attachments, is for the sole use of the > intended recipient(s) and may contain information that is proprietary, > confidential, and exempt from disclosure under applicable law. Any > unauthorized review, use, disclosure, or distribution is prohibited. If > you have received this email in error please notify the sender by return > email and delete the original message. Please note, the recipient should > check this email and any attachments for the presence of viruses. The > organization accepts no liability for any damage caused by any virus > transmitted by this email. > ================================= > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Dear experts and especially Wayne,
please consider the following situation: A___________________________________________ 1. Open an 8-bit image with zoom e.g. 400% 2. Use the point tool 3. Make a point selection at x=5, y=10 according to the coordinates shown in the IJ-toolbar B___________________________________________ 1. Run the macro: // getSelectionBounds( x, y, width, height ); print( round(x), round(y) ); // 2. The log-window shows: 5 10 C___________________________________________ 1. Run the compiled plugin: // import java.awt.*; import ij.*; import ij.gui.*; import ij.process.*; import ij.plugin.filter.PlugInFilter; public class My_PlugInFilter implements PlugInFilter { protected ImagePlus imp; public int setup( String arg, ImagePlus imp ) { if ( IJ.versionLessThan( "1.53g" ) ) return DONE; if( imp != null ) { this.imp = imp; } return DOES_8G; } public void run( ImageProcessor ip ) { Roi roi = imp.getRoi(); int x_0 = (int)Math.round( roi.getBounds().x ); int y_0 = (int)Math.round( roi.getBounds().y ); IJ.log( ""+x_0+"; "+y_0 ); } } // 2. The log-window *sometimes* shows: 5; 10 3. However, in many cases the result is "5; 9", "4; 9", or "4; 10" 4. The plugin-result depends on how the point selection was set in the zoomed image 5. The discrepancy is not observed if the image is not initially zoomed What am I doing wrong? Regards Herbie -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Herbie,
when you create a point selection at zoom level > 150% the coordinates will usually have non-integer values (subpixel resolution). If you have the point tool (not the multi-point tool), you can get the coordinates with Edit>Selection>Properties (shortcut y) and 'List coordinates'. The bounding box with roi.getBounds() is integer. The ROI class also has a method that returns the bounding box with floating-point values: Rectangle2D.Double getFloatBounds() Michael ________________________________________________________________ On 08.01.21 11:10, Herbie wrote: > Dear experts and especially Wayne, > > please consider the following situation: > > A___________________________________________ > 1. Open an 8-bit image with zoom e.g. 400% > 2. Use the point tool > 3. Make a point selection at x=5, y=10 according > to the coordinates shown in the IJ-toolbar > > B___________________________________________ > 1. Run the macro: > // > getSelectionBounds( x, y, width, height ); > print( round(x), round(y) ); > // > 2. The log-window shows: > 5 10 > > C___________________________________________ > 1. Run the compiled plugin: > // > import java.awt.*; > import ij.*; > import ij.gui.*; > import ij.process.*; > import ij.plugin.filter.PlugInFilter; > public class My_PlugInFilter implements PlugInFilter { > protected ImagePlus imp; > public int setup( String arg, ImagePlus imp ) { > if ( IJ.versionLessThan( "1.53g" ) ) > return DONE; > if( imp != null ) { > this.imp = imp; > } > return DOES_8G; > } > public void run( ImageProcessor ip ) { > Roi roi = imp.getRoi(); > int x_0 = (int)Math.round( roi.getBounds().x ); > int y_0 = (int)Math.round( roi.getBounds().y ); > IJ.log( ""+x_0+"; "+y_0 ); > } > } > // > 2. The log-window *sometimes* shows: > 5; 10 > 3. However, in many cases the result is "5; 9", "4; 9", or "4; 10" > 4. The plugin-result depends on how the point selection was set in the > zoomed image > 5. The discrepancy is not observed if the image is not initially zoomed > > What am I doing wrong? > > Regards > > Herbie -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Herbie
Hi Herbie,
the macro functions calls the function getBounds() in Functions.java. This functions returns floating point values after internally calling roi.getFloatBounds() . Your plugin returns roi.getBounds().x and roi.getBounds().y which are floor(roi.getFloatBounds().x) and floor(roi.getFloatBounds().y). Hope that helps Peter On 08.01.2021 11:10, Herbie wrote: > Dear experts and especially Wayne, > > please consider the following situation: > > A___________________________________________ > 1. Open an 8-bit image with zoom e.g. 400% > 2. Use the point tool > 3. Make a point selection at x=5, y=10 according > to the coordinates shown in the IJ-toolbar > > B___________________________________________ > 1. Run the macro: > // > getSelectionBounds( x, y, width, height ); > print( round(x), round(y) ); > // > 2. The log-window shows: > 5 10 > > C___________________________________________ > 1. Run the compiled plugin: > // > import java.awt.*; > import ij.*; > import ij.gui.*; > import ij.process.*; > import ij.plugin.filter.PlugInFilter; > public class My_PlugInFilter implements PlugInFilter { > protected ImagePlus imp; > public int setup( String arg, ImagePlus imp ) { > if ( IJ.versionLessThan( "1.53g" ) ) > return DONE; > if( imp != null ) { > this.imp = imp; > } > return DOES_8G; > } > public void run( ImageProcessor ip ) { > Roi roi = imp.getRoi(); > int x_0 = (int)Math.round( roi.getBounds().x ); > int y_0 = (int)Math.round( roi.getBounds().y ); > IJ.log( ""+x_0+"; "+y_0 ); > } > } > // > 2. The log-window *sometimes* shows: > 5; 10 > 3. However, in many cases the result is "5; 9", "4; 9", or "4; 10" > 4. The plugin-result depends on how the point selection was set in the > zoomed image > 5. The discrepancy is not observed if the image is not initially zoomed > > What am I doing wrong? > > Regards > > Herbie > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Greetings Peter,
yes that explains a lot--thanks! Taking the "floor" instead of "round" appears being a bit strange. __________ As suggested by Michael Schmid, I'm now using: x_0 = (int)Math.round( roi.getFloatBounds().getX() ); y_0 = (int)Math.round( roi.getFloatBounds().getY() ); __________ BTW x_0 = (int)Math.round( roi.getBounds().getX() ); y_0 = (int)Math.round( roi.getBounds().getY() ); doesn't solve the problem, although roi.getBounds().getX() is said to return a Double as well. Regards Herbie :::::::::::::::::::::::::::::::::::::::: Am 08.01.21 um 12:28 schrieb Peter Haub: > Hi Herbie, > > the macro functions calls the function > getBounds() in Functions.java. > This functions returns floating point values after internally calling > roi.getFloatBounds() . > > Your plugin returns roi.getBounds().x and roi.getBounds().y > which are floor(roi.getFloatBounds().x) and floor(roi.getFloatBounds().y). > > Hope that helps > > Peter > > On 08.01.2021 11:10, Herbie wrote: >> Dear experts and especially Wayne, >> >> please consider the following situation: >> >> A___________________________________________ >> 1. Open an 8-bit image with zoom e.g. 400% >> 2. Use the point tool >> 3. Make a point selection at x=5, y=10 according >> to the coordinates shown in the IJ-toolbar >> >> B___________________________________________ >> 1. Run the macro: >> // >> getSelectionBounds( x, y, width, height ); >> print( round(x), round(y) ); >> // >> 2. The log-window shows: >> 5 10 >> >> C___________________________________________ >> 1. Run the compiled plugin: >> // >> import java.awt.*; >> import ij.*; >> import ij.gui.*; >> import ij.process.*; >> import ij.plugin.filter.PlugInFilter; >> public class My_PlugInFilter implements PlugInFilter { >> protected ImagePlus imp; >> public int setup( String arg, ImagePlus imp ) { >> if ( IJ.versionLessThan( "1.53g" ) ) >> return DONE; >> if( imp != null ) { >> this.imp = imp; >> } >> return DOES_8G; >> } >> public void run( ImageProcessor ip ) { >> Roi roi = imp.getRoi(); >> int x_0 = (int)Math.round( roi.getBounds().x ); >> int y_0 = (int)Math.round( roi.getBounds().y ); >> IJ.log( ""+x_0+"; "+y_0 ); >> } >> } >> // >> 2. The log-window *sometimes* shows: >> 5; 10 >> 3. However, in many cases the result is "5; 9", "4; 9", or "4; 10" >> 4. The plugin-result depends on how the point selection was set in the >> zoomed image >> 5. The discrepancy is not observed if the image is not initially zoomed >> >> What am I doing wrong? >> >> Regards >> >> Herbie >> >> -- >> ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Herbie
Hi Herbie,
Thanks to Michael Schmid, the latest daily build (1.53h37) fixes bugs that caused the roi.getBounds() method to not work as expected with polyline and point selections on images zoomed more than 150%. The getBounds() method returns integer values so there is no need to round or convert to int. The getSelectionBounds() macro function in the daily build calls roi.getBounds(), so there is also no need to round the values. Use the new Roi.getFloatBounds() macro function to get the bounds as real numbers. I attached a test macro (with screenshot) that prints and draws the values from Roi.getBounds() (same as getSelectionBounds) and Roi.getFloatBounds(). -wayne Overlay.addSelection Roi.getBounds(x, y, width, height) Roi.getFloatBounds(x2, y2, width2, height2) print("getBounds: "+x, y, width, height) print("getFloatBounds: "+x2, y2, width2, height2) makeRectangle(x, y, width, height) Overlay.addSelection makeRectangle(x2, y2, width2, height2) Overlay.addSelection > On Jan 8, 2021, at 5:10 AM, Herbie <[hidden email]> wrote: > > Dear experts and especially Wayne, > > please consider the following situation: > > A___________________________________________ > 1. Open an 8-bit image with zoom e.g. 400% > 2. Use the point tool > 3. Make a point selection at x=5, y=10 according > to the coordinates shown in the IJ-toolbar > > B___________________________________________ > 1. Run the macro: > // > getSelectionBounds( x, y, width, height ); > print( round(x), round(y) ); > // > 2. The log-window shows: > 5 10 > > C___________________________________________ > 1. Run the compiled plugin: > // > import java.awt.*; > import ij.*; > import ij.gui.*; > import ij.process.*; > import ij.plugin.filter.PlugInFilter; > public class My_PlugInFilter implements PlugInFilter { > protected ImagePlus imp; > public int setup( String arg, ImagePlus imp ) { > if ( IJ.versionLessThan( "1.53g" ) ) > return DONE; > if( imp != null ) { > this.imp = imp; > } > return DOES_8G; > } > public void run( ImageProcessor ip ) { > Roi roi = imp.getRoi(); > int x_0 = (int)Math.round( roi.getBounds().x ); > int y_0 = (int)Math.round( roi.getBounds().y ); > IJ.log( ""+x_0+"; "+y_0 ); > } > } > // > 2. The log-window *sometimes* shows: > 5; 10 > 3. However, in many cases the result is "5; 9", "4; 9", or "4; 10" > 4. The plugin-result depends on how the point selection was set in the zoomed image > 5. The discrepancy is not observed if the image is not initially zoomed > > What am I doing wrong? > > Regards > > Herbie -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html Screenshot.png (233K) Download Attachment |
Dear Wayne,
dear Michael Schmid, many thanks for your immediate help and action! Point-RoI coordinates always appear now as expected when using: x_0 = roi.getBounds().x; y_0 = roi.getBounds().y; Best Herbie :::::::::::::::::::::::::::::::::::::::::: Am 11.01.21 um 00:54 schrieb Wayne Rasband: > Hi Herbie, > > Thanks to Michael Schmid, the latest daily build (1.53h37) fixes bugs that caused the roi.getBounds() method to not work as expected with polyline and point selections on images zoomed more than 150%. The getBounds() method returns integer values so there is no need to round or convert to int. > > The getSelectionBounds() macro function in the daily build calls roi.getBounds(), so there is also no need to round the values. Use the new Roi.getFloatBounds() macro function to get the bounds as real numbers. > > I attached a test macro (with screenshot) that prints and draws the values from Roi.getBounds() (same as getSelectionBounds) and Roi.getFloatBounds(). > > -wayne > > Overlay.addSelection > Roi.getBounds(x, y, width, height) > Roi.getFloatBounds(x2, y2, width2, height2) > print("getBounds: "+x, y, width, height) > print("getFloatBounds: "+x2, y2, width2, height2) > makeRectangle(x, y, width, height) > Overlay.addSelection > makeRectangle(x2, y2, width2, height2) > Overlay.addSelection > > > > > > >> On Jan 8, 2021, at 5:10 AM, Herbie <[hidden email]> wrote: >> >> Dear experts and especially Wayne, >> >> please consider the following situation: >> >> A___________________________________________ >> 1. Open an 8-bit image with zoom e.g. 400% >> 2. Use the point tool >> 3. Make a point selection at x=5, y=10 according >> to the coordinates shown in the IJ-toolbar >> >> B___________________________________________ >> 1. Run the macro: >> // >> getSelectionBounds( x, y, width, height ); >> print( round(x), round(y) ); >> // >> 2. The log-window shows: >> 5 10 >> >> C___________________________________________ >> 1. Run the compiled plugin: >> // >> import java.awt.*; >> import ij.*; >> import ij.gui.*; >> import ij.process.*; >> import ij.plugin.filter.PlugInFilter; >> public class My_PlugInFilter implements PlugInFilter { >> protected ImagePlus imp; >> public int setup( String arg, ImagePlus imp ) { >> if ( IJ.versionLessThan( "1.53g" ) ) >> return DONE; >> if( imp != null ) { >> this.imp = imp; >> } >> return DOES_8G; >> } >> public void run( ImageProcessor ip ) { >> Roi roi = imp.getRoi(); >> int x_0 = (int)Math.round( roi.getBounds().x ); >> int y_0 = (int)Math.round( roi.getBounds().y ); >> IJ.log( ""+x_0+"; "+y_0 ); >> } >> } >> // >> 2. The log-window *sometimes* shows: >> 5; 10 >> 3. However, in many cases the result is "5; 9", "4; 9", or "4; 10" >> 4. The plugin-result depends on how the point selection was set in the zoomed image >> 5. The discrepancy is not observed if the image is not initially zoomed >> >> What am I doing wrong? >> >> Regards >> >> Herbie > > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Fred Damen
> On Jan 21, 2021, at 1:09 PM, Herbie <[hidden email]> wrote:
> > Dear experts and especially Wayne, > > please consider the following situation: Hi Herbie, You will get the expected results if your plugin assigns the ROI to the ImageProcessor. For example, when I run this macro newImage("TestNoise", "8-bit noise", 256, 256, 1); makeOval( 124, 124, 9, 9 ); print("macro mean="+getValue("Mean")); and then this script imp = IJ.getImage(); ip = imp.getProcessor(); ip.setRoi(new OvalRoi(124, 124, 9, 9)); IJ.log("script mean="+ip.getStatistics().mean); I get this output macro mean=124.4493 script mean=124.44927536231884 Or better, in your plugin, use imp = IJ.getImage(); imp.setRoi(new OvalRoi(124, 124, 9, 9)); IJ.log("script mean="+imp.getStatistics().mean); Note that your plugin would be simpler and easier to understand if it implanted the PlugIn interface. -wayne > A___________________________________________ > // create a test pattern > newImage("TestNoise", "8-bit noise", 256, 256, 1); > > B___________________________________________ > // with image "TestNoise" run the macro: > makeOval( 124, 124, 9, 9 ); > print( "macro mean: "+d2s(getValue("Mean"), 9)+";" ); > // > > C___________________________________________ > // with image "TestNoise" run the compiled plugin: > import java.awt.*; > import ij.*; > import ij.gui.*; > import ij.process.*; > import ij.plugin.filter.PlugInFilter; > public class My_PlugInFilter implements PlugInFilter { > protected ImagePlus imp; > public int setup( String arg, ImagePlus imp ) { > if ( IJ.versionLessThan( "1.53g" ) ) > return DONE; > if( imp != null ) { > this.imp = imp; > } > return DOES_8G; > } > public void run( ImageProcessor ip ) { > imp.setRoi( new OvalRoi( 124, 124, 9, 9 ) ); > IJ.log("plugin mean: "+imp.getProcessor().getStatistics().mean+";"); > } > } > // > > In general the resulting mean values are discrepant. > Here are example values I got from the same image and RoI: > macro mean 126.463768116; > plugin mean 129.2962962962963; > > > What am I doing wrong? > > Regards > > Herbie -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Free forum by Nabble | Edit this page |