Thanks for this clarification.
I already suspected that the results columns order was hard-coded for compatibility. With the new Table.applyMacro function it will be easy to copy columns one by one, so one can append copied columns to the right of the table with new names in the desired order, and thereafter delete the old columns. This way one would get the desired layout without looping through all values. This example macro seems to work as intended: run("Blobs (25K)"); run("Set Measurements...", "area mean standard modal min centroid center perimeter bounding fit shape feret's stack display redirect=None decimal=6"); setAutoThreshold("Default"); run("Analyze Particles...", "display clear include in_situ"); Table.applyMacro("FeretMinimum=MinFeret", "Results"); Table.applyMacro("FeretMaximum=Feret", "Results"); Table.applyMacro("FeretAngleCopy=FeretAngle", "Results"); Table.applyMacro("FeretStartX=FeretX", "Results"); Table.applyMacro("FeretStartY=FeretY", "Results"); Table.deleteColumn("MinFeret", "Results"); Table.deleteColumn("Feret", "Results"); Table.deleteColumn("FeretAngle", "Results"); Table.deleteColumn("FeretX", "Results"); Table.deleteColumn("FeretY", "Results"); in this context a new Table.renameColumn(oldName, newName, tableName) command could be useful? For example, Table.renameColumn ("FeretAngleCopy", "FeretAngle", "Results"); Stein -----Original Message----- From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of Michael Schmid Sent: 10. april 2018 15:45 To: [hidden email] Subject: Re: How to create a customised results table and add data to it within a macro Hi Stein, the standard headings of the ResultsTable are hardcoded. Unfortunately one cannot easily change this since it would break user plugins that access them by their number. This is also the reason for the non-intuitive ordering of the Feret items; "Feret" (min Feret diameter) was in ImageJ since the early days; the others were added later, when a few additional columns were already in between. (In principle this could be changed, but it would be some effort; it would require a translation table from the old numbers to the corresponding headings). Scaled Z: Yes, you can have a macro for this like, e.g. Table.applyMacro("x=0; y=0; Z=Slice-1; toScaled(x,y,Z);"); (It assumes that the current image window has the same calibration as the Results table; it also accounts for any offset of the origin in z direction). Michael ________________________________________________________________ On 09/04/2018 22:32, Stein Rørvik wrote: > Thank you for this clarification; I was not aware of this difference between string-based and numerical tables. > > Could it still make sense with a Table.setHeader(<tabdelimited string>) command for newly created numerical tables? > > This would then create an empty table with the desired column headers in the desired order; instead of new columns just appearing in an arbitrary order at first use. One thing that annoys me with the existing Results table is that there is no Z column for calibrated Z positions, and the Feret shape parameters are not placed in any logical order. If one could pre-set the column order, that would fix this easily. For example, MinFeret, Feret, FeretAngle, FeretX, FeretY. Also, Table.applyMacro("Z=Slice*<MicronsPerPixelZ>","Result") would easily add the missing Z coordinate column. > > Stein > > -----Original Message----- > From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of > Michael Schmid > Sent: 09. april 2018 19:56 > To: [hidden email] > Subject: Re: How to create a customised results table and add data to > it within a macro > > Hi Stein, > > a few remarks on tables: > > Beware that there are two different types of tables in ImageJ: > > (1) Tables like the ResultsTable, the one you get from Plots with "List", and tables with contents filled in by the new macro Table... > commands are essentially numeric (there is a predefined "label" column, which must be the first one, this one is text-only). > > One can have non-numeric (String) values in other columns, then Table.get(colName, row) will give you NaN (not a number) and you need Table.getString(colName, row). But one would not do the for numbers; and applyMacro will work with the numeric value. > > For this type of tables, the column headers are fixed. The underlying data structure currently does not support renaming column headers. > The column headers are simply created by assigning values to columns (by column name); if a column does not exist, it is created. > > (2) On the other hand, if you create a table by macro print commands, it is a pure list of Strings, with no numeric values behind it. You can't do any calculations with it, and the Table... commands don't work with it. The purpose of this type of table is only displaying values and saving or copying to the clipboard. > > > This means that all commands using Strings like > "Table.addRow(<tabdelimited string>)" for numeric tables would be > problematic: It would require conversion of text to numbers; note that > number>text>number conversion induces a loss of precision (unless the > data are integer or the number of digits is very large). > > So it would be better to copy numeric values as such, not via String > manipulation. > > > Michael > ________________________________________________________________ > > > On 09/04/2018 17:07, Stein Rørvik wrote: >> Thanks, exactly what I need. These functions will be very useful for manipulating an existing results table. >> I already tried Table.applyMacro("Results", "DoubleArea=Area*2") with daily build 1.52a39 and it worked as expected. >> >> Today I use a similar approach as Timothy outlined: I create a new table, read the results from the old one, and use the getResult / setResult functions to create a new table. I also sometimes split lines and use the print(tablename, ... ) syntax to print tab-delimited headers and rows with the new table; this approach is much faster. >> >> To add to the below list, I think the functions >> Table.setHeader(<tabdelimited string>) and Table.addRow(<tabdelimited >> string>), Table.updateRow(<rowindex>, <tabdelimited string>) would be useful for writing contents in batch. >> >> Also, perhaps Table.headings() could be complemented with >> Table.rows() to return all the rows (except the header) as >> tab-delimited strings concatenated by \n as well as Table.content() >> to return everything as a string (headers plus all the rows) >> >> Stein >> >> -----Original Message----- >> From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of >> Michael Schmid >> Sent: 09. april 2018 16:33 >> To: [hidden email] >> Subject: Re: How to create a customised results table and add data to >> it within a macro >> >> Hi Stein, >> >> the Table.* functions are currently under development; they are in the daily build only. >> >> The list of currently implemented commands is in the Release notes: >> https://github.com/imagej/imagej1/blob/master/release-notes.html >> >> Table.create() - opens a new table >> Table.size() - number of rows in the table >> Table.title() - title of the current table >> Table.headings() - column headings as a tab-delimited string >> Table.get(columnName, rowIndex) - returns a numeric value >> Table.getString(columnName, rowIndex) - returns a string value >> Table.set(columnName, rowIndex, value) - sets numeric or string value >> Table.update() - updates table window >> Table.reset() - resets (clears) the table >> Table.applyMacro(macro) - applies macro code to table >> Table.rename(title1, title2) - renames a table >> Table.save(filePath) - saves the table >> Table.deleteRows(index1, index2) - deletes specified rows >> Table.deleteColumn(columnName) - deletes specified column >> Table.hideRowNumbers() - disables display of row numbers >> >> >> You can also specify the title of a table, this argument goes last. >> >> So e.g. the macro I had suggested last week has to be changed to: >> myName = "01.txt"; >> Table.applyMacro("_='"+myName+" '+_", "Results"); >> >> If no title is given, the commands refer the main "Results" table or to the current foreground window (if it has a table). >> Inside the macro of 'apply macro', if no title is given, the Table commands refer to the table processed by the macro. >> >> Note that these commands are still experimental. Things may still change, so you may have to adapt your macros in case of changes! >> >> >> Michael >> ________________________________________________________________ >> On 09/04/2018 12:43, Stein Rørvik wrote: >>> Table.applyMacro seems very useful, but I cannot see it documented >>> in the https://imagej.nih.gov/ij/developer/macro/functions.html webpage? >>> Are there any other Table.* functions implemented in ImageJ ? >>> >>> Stein >>> >>> -----Original Message----- >>> From: ImageJ Interest Group [mailto:[hidden email]] On Behalf >>> Of Michael Schmid >>> Sent: 28. mars 2018 18:51 >>> To: [hidden email] >>> Subject: Re: How to create a customised results table and add data >>> to it within a macro >>> >>> Hi Herbie & dschones, >>> >>> the first column with the 'Y123' etc. is the "row label", not a standard column. In a macro, you can get and set it with >>> getResultLabel(row) and >>> setResult("Label", row, string). >>> >>> With today's daily build (Help>Update ImageJ), you can also modify it without a loop over all rows: >>> >>> myName = "01.txt"; >>> Table.applyMacro("Results", "_='"+myName+" '+_"); >>> >>> (Since the "row label" column has an empty name in this case, its >>> name is mapped to an underscore as variable name.) >>> >>> This gives you a space, not a tab between the '01.txt' and the 'Y123' >>> >>> In principle, one could add a tab, but that would shift all columns to the right. The headers won't get shifted, and I don't think that one could also shift the headers. >>> >>> By the way, you can have Strings and numbers mixed in one column, but it won't help you here. E.g., if there is a column "X123", this works: >>> setResult("X123", 1, "hello"); >>> >>> >>> Michael >>> ________________________________________________________________ >>> >>> >>> On 28/03/2018 17:58, Herbie wrote: >>>> Would it be ok to have the filename in a new first column: >>>> >>>> X936 X937 X938 01.txt Y516 01.txt >>>> Y517 01.txt Y518 01.txt Y519 01.txt Y520 >>>> >>>> 02.txt Y516 >>>> 02.txt Y517 >>>> 02.txt Y518 >>>> 02.txt Y519 >>>> 02.txt Y520 >>>> >>>> or something like: >>>> >>>> X936_01.txt X937_01.txt X938_01.txt X936_02.txt >>>> X937_02.txt X938_02.txt (watch for line breaks) >>>> Y516 >>>> Y517 >>>> Y518 >>>> Y519 >>>> Y520 >>>> >>>> or something along these lines: >>>> >>>> 01.txt X936 X937 X938 02.txt X936 X937 X938 >>>> Y516 Y516 >>>> Y517 Y517 >>>> Y518 Y518 >>>> Y519 Y519 >>>> Y520 Y520 >>>> >>>> >>>> AFAIK it is not possible to have numbers and letters in the same >>>> column except in the column headers. >>>> >>>> Please be aware of the fact that ImageJ is not a spread-sheet >>>> program, but serves for image processing in the first place. >>>> >>>> Regards >>>> >>>> Herbie >>>> >>>> :::::::::::::::::::::::::::::::::::::: >>>> Am 28.03.18 um 17:35 schrieb dschones: >>>>> Hi Herbie, >>>>> >>>>> I'll just leave the generation of the results as they are and give >>>>> the reference to the way I found getting the filename into first >>>>> line of the results.txt >>>>> >>>>> https://askubuntu.com/questions/1019727/inserting-file-name-in-fir >>>>> st-line-of-merged-txt-files >>>>> >>>>> <https://askubuntu.com/questions/1019727/inserting-file-name-in-fi >>>>> rst-line-of-merged-txt-files> >>>>> >>>>> >>>>> Good afternoon! :) >>>> >>>> -- >>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html >>> >>> -- >>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html >>> >>> -- >>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html >>> >> >> -- >> ImageJ mailing list: http://imagej.nih.gov/ij/list.html >> >> -- >> ImageJ mailing list: http://imagej.nih.gov/ij/list.html >> > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
> On Apr 12, 2018, at 7:31 AM, Stein Rørvik <[hidden email]> wrote:
> > Thanks for this clarification. > I already suspected that the results columns order was hard-coded for compatibility. > > With the new Table.applyMacro function it will be easy to copy columns one by one, so one can append copied columns to the right of the table with new names in the desired order, and thereafter delete the old columns. This way one would get the desired layout without looping through all values. > > This example macro seems to work as intended: The latest daily build (1.52a47) adds a Table.renameColumn(oldName, newName) function. Here is an updated version of the example macro that uses it: run("Blobs (25K)"); run("Set Measurements...", "area mean centroid feret's"); setAutoThreshold("Default"); Table.reset("Results"); run("Analyze Particles...", "display include in_situ"); code = "FeretMinimum=MinFeret; FeretMaximum=Feret;" +"FeretAngleCopy=FeretAngle; FeretStartX=FeretX;" +"FeretStartY=FeretY"; Table.applyMacro(code); Table.deleteColumn("MinFeret"); Table.deleteColumn("Feret"); Table.deleteColumn("FeretAngle"); Table.deleteColumn("FeretX"); Table.deleteColumn("FeretY"); Table.renameColumn("FeretAngleCopy", "FeretAngle"); Table.update; The “Results” arguments in the original version are not needed since Table.reset("Results”) makes “Results” the current (active) table. All five columns are copied in one call to Table.applyMacro() since this is more efficient. The Table.update call is needed since Table.deleteColumn() and Table.renameColumn() do not update the display. Here is a list of the currently available Table.* functions: Table.create(table) - opens a new table Table.reset(table) - resets (clears) the table Table.size() - number of rows in the table Table.title() - title of the current table Table.headings() - column headings as a tab-delimited string Table.get(columnName, rowIndex) - returns a numeric value Table.getString(columnName, rowIndex) - returns a string value Table.set(columnName, rowIndex, value) - sets numeric or string value Table.update() - updates table window Table.applyMacro(macro) - applies macro code to table Table.rename(title1, title2) - renames a table Table.save(filePath) - saves the table Table.deleteRows(index1, index2) - deletes specified rows Table.renameColumn(oldName, newName) - renames a column Table.deleteColumn(columnName) - deletes specified column Table.showRowNumbers(boolean) - enable/disable row numbers And here are more example macros: http://wsr.imagej.net/macros/Sine_Cosine_Table2.txt http://wsr.imagej.net/macros/Make_Duplicate_Table.txt http://wsr.imagej.net/macros/Access_Plot_Data.txt http://wsr.imagej.net/macros/Access_Summary_Table.txt http://wsr.imagej.net/macros/Access_Overlay_Elements_Table.txt -wayne > > run("Blobs (25K)"); > run("Set Measurements...", "area mean standard modal min centroid center perimeter bounding fit shape feret's stack display redirect=None decimal=6"); > setAutoThreshold("Default"); > run("Analyze Particles...", "display clear include in_situ"); > Table.applyMacro("FeretMinimum=MinFeret", "Results"); > Table.applyMacro("FeretMaximum=Feret", "Results"); > Table.applyMacro("FeretAngleCopy=FeretAngle", "Results"); > Table.applyMacro("FeretStartX=FeretX", "Results"); > Table.applyMacro("FeretStartY=FeretY", "Results"); > Table.deleteColumn("MinFeret", "Results"); > Table.deleteColumn("Feret", "Results"); > Table.deleteColumn("FeretAngle", "Results"); > Table.deleteColumn("FeretX", "Results"); > Table.deleteColumn("FeretY", "Results"); > > in this context a new Table.renameColumn(oldName, newName, tableName) command could be useful? > For example, Table.renameColumn ("FeretAngleCopy", "FeretAngle", "Results"); > > Stein > > -----Original Message----- > From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of Michael Schmid > Sent: 10. april 2018 15:45 > To: [hidden email] > Subject: Re: How to create a customised results table and add data to it within a macro > > Hi Stein, > > the standard headings of the ResultsTable are hardcoded. Unfortunately one cannot easily change this since it would break user plugins that access them by their number. This is also the reason for the non-intuitive ordering of the Feret items; "Feret" (min Feret diameter) was in ImageJ since the early days; the others were added later, when a few additional columns were already in between. > > (In principle this could be changed, but it would be some effort; it would require a translation table from the old numbers to the corresponding headings). > > Scaled Z: > Yes, you can have a macro for this like, e.g. > Table.applyMacro("x=0; y=0; Z=Slice-1; toScaled(x,y,Z);"); (It assumes that the current image window has the same calibration as the Results table; it also accounts for any offset of the origin in z direction). > > > Michael > ________________________________________________________________ > On 09/04/2018 22:32, Stein Rørvik wrote: >> Thank you for this clarification; I was not aware of this difference between string-based and numerical tables. >> >> Could it still make sense with a Table.setHeader(<tabdelimited string>) command for newly created numerical tables? >> >> This would then create an empty table with the desired column headers in the desired order; instead of new columns just appearing in an arbitrary order at first use. One thing that annoys me with the existing Results table is that there is no Z column for calibrated Z positions, and the Feret shape parameters are not placed in any logical order. If one could pre-set the column order, that would fix this easily. For example, MinFeret, Feret, FeretAngle, FeretX, FeretY. Also, Table.applyMacro("Z=Slice*<MicronsPerPixelZ>","Result") would easily add the missing Z coordinate column. >> >> Stein >> >> -----Original Message----- >> From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of >> Michael Schmid >> Sent: 09. april 2018 19:56 >> To: [hidden email] >> Subject: Re: How to create a customised results table and add data to >> it within a macro >> >> Hi Stein, >> >> a few remarks on tables: >> >> Beware that there are two different types of tables in ImageJ: >> >> (1) Tables like the ResultsTable, the one you get from Plots with "List", and tables with contents filled in by the new macro Table... >> commands are essentially numeric (there is a predefined "label" column, which must be the first one, this one is text-only). >> >> One can have non-numeric (String) values in other columns, then Table.get(colName, row) will give you NaN (not a number) and you need Table.getString(colName, row). But one would not do the for numbers; and applyMacro will work with the numeric value. >> >> For this type of tables, the column headers are fixed. The underlying data structure currently does not support renaming column headers. >> The column headers are simply created by assigning values to columns (by column name); if a column does not exist, it is created. >> >> (2) On the other hand, if you create a table by macro print commands, it is a pure list of Strings, with no numeric values behind it. You can't do any calculations with it, and the Table... commands don't work with it. The purpose of this type of table is only displaying values and saving or copying to the clipboard. >> >> >> This means that all commands using Strings like >> "Table.addRow(<tabdelimited string>)" for numeric tables would be >> problematic: It would require conversion of text to numbers; note that >> number>text>number conversion induces a loss of precision (unless the >> data are integer or the number of digits is very large). >> >> So it would be better to copy numeric values as such, not via String >> manipulation. >> >> >> Michael >> ________________________________________________________________ >> >> >> On 09/04/2018 17:07, Stein Rørvik wrote: >>> Thanks, exactly what I need. These functions will be very useful for manipulating an existing results table. >>> I already tried Table.applyMacro("Results", "DoubleArea=Area*2") with daily build 1.52a39 and it worked as expected. >>> >>> Today I use a similar approach as Timothy outlined: I create a new table, read the results from the old one, and use the getResult / setResult functions to create a new table. I also sometimes split lines and use the print(tablename, ... ) syntax to print tab-delimited headers and rows with the new table; this approach is much faster. >>> >>> To add to the below list, I think the functions >>> Table.setHeader(<tabdelimited string>) and Table.addRow(<tabdelimited >>> string>), Table.updateRow(<rowindex>, <tabdelimited string>) would be useful for writing contents in batch. >>> >>> Also, perhaps Table.headings() could be complemented with >>> Table.rows() to return all the rows (except the header) as >>> tab-delimited strings concatenated by \n as well as Table.content() >>> to return everything as a string (headers plus all the rows) >>> >>> Stein >>> >>> -----Original Message----- >>> From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of >>> Michael Schmid >>> Sent: 09. april 2018 16:33 >>> To: [hidden email] >>> Subject: Re: How to create a customised results table and add data to >>> it within a macro >>> >>> Hi Stein, >>> >>> the Table.* functions are currently under development; they are in the daily build only. >>> >>> The list of currently implemented commands is in the Release notes: >>> https://github.com/imagej/imagej1/blob/master/release-notes.html >>> >>> Table.create() - opens a new table >>> Table.size() - number of rows in the table >>> Table.title() - title of the current table >>> Table.headings() - column headings as a tab-delimited string >>> Table.get(columnName, rowIndex) - returns a numeric value >>> Table.getString(columnName, rowIndex) - returns a string value >>> Table.set(columnName, rowIndex, value) - sets numeric or string value >>> Table.update() - updates table window >>> Table.reset() - resets (clears) the table >>> Table.applyMacro(macro) - applies macro code to table >>> Table.rename(title1, title2) - renames a table >>> Table.save(filePath) - saves the table >>> Table.deleteRows(index1, index2) - deletes specified rows >>> Table.deleteColumn(columnName) - deletes specified column >>> Table.hideRowNumbers() - disables display of row numbers >>> >>> >>> You can also specify the title of a table, this argument goes last. >>> >>> So e.g. the macro I had suggested last week has to be changed to: >>> myName = "01.txt"; >>> Table.applyMacro("_='"+myName+" '+_", "Results"); >>> >>> If no title is given, the commands refer the main "Results" table or to the current foreground window (if it has a table). >>> Inside the macro of 'apply macro', if no title is given, the Table commands refer to the table processed by the macro. >>> >>> Note that these commands are still experimental. Things may still change, so you may have to adapt your macros in case of changes! >>> >>> >>> Michael >>> ________________________________________________________________ >>> On 09/04/2018 12:43, Stein Rørvik wrote: >>>> Table.applyMacro seems very useful, but I cannot see it documented >>>> in the https://imagej.nih.gov/ij/developer/macro/functions.html webpage? >>>> Are there any other Table.* functions implemented in ImageJ ? >>>> >>>> Stein >>>> >>>> -----Original Message----- >>>> From: ImageJ Interest Group [mailto:[hidden email]] On Behalf >>>> Of Michael Schmid >>>> Sent: 28. mars 2018 18:51 >>>> To: [hidden email] >>>> Subject: Re: How to create a customised results table and add data >>>> to it within a macro >>>> >>>> Hi Herbie & dschones, >>>> >>>> the first column with the 'Y123' etc. is the "row label", not a standard column. In a macro, you can get and set it with >>>> getResultLabel(row) and >>>> setResult("Label", row, string). >>>> >>>> With today's daily build (Help>Update ImageJ), you can also modify it without a loop over all rows: >>>> >>>> myName = "01.txt"; >>>> Table.applyMacro("Results", "_='"+myName+" '+_"); >>>> >>>> (Since the "row label" column has an empty name in this case, its >>>> name is mapped to an underscore as variable name.) >>>> >>>> This gives you a space, not a tab between the '01.txt' and the 'Y123' >>>> >>>> In principle, one could add a tab, but that would shift all columns to the right. The headers won't get shifted, and I don't think that one could also shift the headers. >>>> >>>> By the way, you can have Strings and numbers mixed in one column, but it won't help you here. E.g., if there is a column "X123", this works: >>>> setResult("X123", 1, "hello"); >>>> >>>> >>>> Michael >>>> ________________________________________________________________ -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Thank you!
The new Table.applyMacro function makes it a lot easier to reorganize the results column-wise in bulk and create new columns with calculated data. Perhaps the below example macro or something similar could be uploaded to the macro directory of the website? I also wonder, in the code section of the macro, is the row number accessible as a predefined variable or function so that it can be used in the Table.applyMacro calculations? Stein -----Original Message----- From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of Wayne Rasband Sent: 13. april 2018 00:26 To: [hidden email] Subject: Re: How to create a customised results table and add data to it within a macro > On Apr 12, 2018, at 7:31 AM, Stein Rørvik <[hidden email]> wrote: > > Thanks for this clarification. > I already suspected that the results columns order was hard-coded for compatibility. > > With the new Table.applyMacro function it will be easy to copy columns one by one, so one can append copied columns to the right of the table with new names in the desired order, and thereafter delete the old columns. This way one would get the desired layout without looping through all values. > > This example macro seems to work as intended: The latest daily build (1.52a47) adds a Table.renameColumn(oldName, newName) function. Here is an updated version of the example macro that uses it: run("Blobs (25K)"); run("Set Measurements...", "area mean centroid feret's"); setAutoThreshold("Default"); Table.reset("Results"); run("Analyze Particles...", "display include in_situ"); code = "FeretMinimum=MinFeret; FeretMaximum=Feret;" +"FeretAngleCopy=FeretAngle; FeretStartX=FeretX;" +"FeretStartY=FeretY"; Table.applyMacro(code); Table.deleteColumn("MinFeret"); Table.deleteColumn("Feret"); Table.deleteColumn("FeretAngle"); Table.deleteColumn("FeretX"); Table.deleteColumn("FeretY"); Table.renameColumn("FeretAngleCopy", "FeretAngle"); Table.update; The “Results” arguments in the original version are not needed since Table.reset("Results”) makes “Results” the current (active) table. All five columns are copied in one call to Table.applyMacro() since this is more efficient. The Table.update call is needed since Table.deleteColumn() and Table.renameColumn() do not update the display. Here is a list of the currently available Table.* functions: Table.create(table) - opens a new table Table.reset(table) - resets (clears) the table Table.size() - number of rows in the table Table.title() - title of the current table Table.headings() - column headings as a tab-delimited string Table.get(columnName, rowIndex) - returns a numeric value Table.getString(columnName, rowIndex) - returns a string value Table.set(columnName, rowIndex, value) - sets numeric or string value Table.update() - updates table window Table.applyMacro(macro) - applies macro code to table Table.rename(title1, title2) - renames a table Table.save(filePath) - saves the table Table.deleteRows(index1, index2) - deletes specified rows Table.renameColumn(oldName, newName) - renames a column Table.deleteColumn(columnName) - deletes specified column Table.showRowNumbers(boolean) - enable/disable row numbers And here are more example macros: http://wsr.imagej.net/macros/Sine_Cosine_Table2.txt http://wsr.imagej.net/macros/Make_Duplicate_Table.txt http://wsr.imagej.net/macros/Access_Plot_Data.txt http://wsr.imagej.net/macros/Access_Summary_Table.txt http://wsr.imagej.net/macros/Access_Overlay_Elements_Table.txt -wayne > > run("Blobs (25K)"); > run("Set Measurements...", "area mean standard modal min centroid > center perimeter bounding fit shape feret's stack display > redirect=None decimal=6"); setAutoThreshold("Default"); run("Analyze > Particles...", "display clear include in_situ"); > Table.applyMacro("FeretMinimum=MinFeret", "Results"); > Table.applyMacro("FeretMaximum=Feret", "Results"); > Table.applyMacro("FeretAngleCopy=FeretAngle", "Results"); > Table.applyMacro("FeretStartX=FeretX", "Results"); > Table.applyMacro("FeretStartY=FeretY", "Results"); > Table.deleteColumn("MinFeret", "Results"); Table.deleteColumn("Feret", > "Results"); Table.deleteColumn("FeretAngle", "Results"); > Table.deleteColumn("FeretX", "Results"); Table.deleteColumn("FeretY", > "Results"); > > in this context a new Table.renameColumn(oldName, newName, tableName) command could be useful? > For example, Table.renameColumn ("FeretAngleCopy", "FeretAngle", > "Results"); > > Stein > > -----Original Message----- > From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of > Michael Schmid > Sent: 10. april 2018 15:45 > To: [hidden email] > Subject: Re: How to create a customised results table and add data to > it within a macro > > Hi Stein, > > the standard headings of the ResultsTable are hardcoded. Unfortunately one cannot easily change this since it would break user plugins that access them by their number. This is also the reason for the non-intuitive ordering of the Feret items; "Feret" (min Feret diameter) was in ImageJ since the early days; the others were added later, when a few additional columns were already in between. > > (In principle this could be changed, but it would be some effort; it would require a translation table from the old numbers to the corresponding headings). > > Scaled Z: > Yes, you can have a macro for this like, e.g. > Table.applyMacro("x=0; y=0; Z=Slice-1; toScaled(x,y,Z);"); (It assumes that the current image window has the same calibration as the Results table; it also accounts for any offset of the origin in z direction). > > > Michael > ________________________________________________________________ > On 09/04/2018 22:32, Stein Rørvik wrote: >> Thank you for this clarification; I was not aware of this difference between string-based and numerical tables. >> >> Could it still make sense with a Table.setHeader(<tabdelimited string>) command for newly created numerical tables? >> >> This would then create an empty table with the desired column headers in the desired order; instead of new columns just appearing in an arbitrary order at first use. One thing that annoys me with the existing Results table is that there is no Z column for calibrated Z positions, and the Feret shape parameters are not placed in any logical order. If one could pre-set the column order, that would fix this easily. For example, MinFeret, Feret, FeretAngle, FeretX, FeretY. Also, Table.applyMacro("Z=Slice*<MicronsPerPixelZ>","Result") would easily add the missing Z coordinate column. >> >> Stein >> >> -----Original Message----- >> From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of >> Michael Schmid >> Sent: 09. april 2018 19:56 >> To: [hidden email] >> Subject: Re: How to create a customised results table and add data to >> it within a macro >> >> Hi Stein, >> >> a few remarks on tables: >> >> Beware that there are two different types of tables in ImageJ: >> >> (1) Tables like the ResultsTable, the one you get from Plots with "List", and tables with contents filled in by the new macro Table... >> commands are essentially numeric (there is a predefined "label" column, which must be the first one, this one is text-only). >> >> One can have non-numeric (String) values in other columns, then Table.get(colName, row) will give you NaN (not a number) and you need Table.getString(colName, row). But one would not do the for numbers; and applyMacro will work with the numeric value. >> >> For this type of tables, the column headers are fixed. The underlying data structure currently does not support renaming column headers. >> The column headers are simply created by assigning values to columns (by column name); if a column does not exist, it is created. >> >> (2) On the other hand, if you create a table by macro print commands, it is a pure list of Strings, with no numeric values behind it. You can't do any calculations with it, and the Table... commands don't work with it. The purpose of this type of table is only displaying values and saving or copying to the clipboard. >> >> >> This means that all commands using Strings like >> "Table.addRow(<tabdelimited string>)" for numeric tables would be >> problematic: It would require conversion of text to numbers; note >> that >> number>text>number conversion induces a loss of precision (unless the >> data are integer or the number of digits is very large). >> >> So it would be better to copy numeric values as such, not via String >> manipulation. >> >> >> Michael >> ________________________________________________________________ >> >> >> On 09/04/2018 17:07, Stein Rørvik wrote: >>> Thanks, exactly what I need. These functions will be very useful for manipulating an existing results table. >>> I already tried Table.applyMacro("Results", "DoubleArea=Area*2") with daily build 1.52a39 and it worked as expected. >>> >>> Today I use a similar approach as Timothy outlined: I create a new table, read the results from the old one, and use the getResult / setResult functions to create a new table. I also sometimes split lines and use the print(tablename, ... ) syntax to print tab-delimited headers and rows with the new table; this approach is much faster. >>> >>> To add to the below list, I think the functions >>> Table.setHeader(<tabdelimited string>) and >>> Table.addRow(<tabdelimited >>> string>), Table.updateRow(<rowindex>, <tabdelimited string>) would be useful for writing contents in batch. >>> >>> Also, perhaps Table.headings() could be complemented with >>> Table.rows() to return all the rows (except the header) as >>> tab-delimited strings concatenated by \n as well as Table.content() >>> to return everything as a string (headers plus all the rows) >>> >>> Stein >>> >>> -----Original Message----- >>> From: ImageJ Interest Group [mailto:[hidden email]] On Behalf >>> Of Michael Schmid >>> Sent: 09. april 2018 16:33 >>> To: [hidden email] >>> Subject: Re: How to create a customised results table and add data >>> to it within a macro >>> >>> Hi Stein, >>> >>> the Table.* functions are currently under development; they are in the daily build only. >>> >>> The list of currently implemented commands is in the Release notes: >>> https://github.com/imagej/imagej1/blob/master/release-notes.html >>> >>> Table.create() - opens a new table >>> Table.size() - number of rows in the table >>> Table.title() - title of the current table >>> Table.headings() - column headings as a tab-delimited string >>> Table.get(columnName, rowIndex) - returns a numeric value >>> Table.getString(columnName, rowIndex) - returns a string value >>> Table.set(columnName, rowIndex, value) - sets numeric or string value >>> Table.update() - updates table window >>> Table.reset() - resets (clears) the table >>> Table.applyMacro(macro) - applies macro code to table >>> Table.rename(title1, title2) - renames a table >>> Table.save(filePath) - saves the table >>> Table.deleteRows(index1, index2) - deletes specified rows >>> Table.deleteColumn(columnName) - deletes specified column >>> Table.hideRowNumbers() - disables display of row numbers >>> >>> >>> You can also specify the title of a table, this argument goes last. >>> >>> So e.g. the macro I had suggested last week has to be changed to: >>> myName = "01.txt"; >>> Table.applyMacro("_='"+myName+" '+_", "Results"); >>> >>> If no title is given, the commands refer the main "Results" table or to the current foreground window (if it has a table). >>> Inside the macro of 'apply macro', if no title is given, the Table commands refer to the table processed by the macro. >>> >>> Note that these commands are still experimental. Things may still change, so you may have to adapt your macros in case of changes! >>> >>> >>> Michael >>> ________________________________________________________________ >>> On 09/04/2018 12:43, Stein Rørvik wrote: >>>> Table.applyMacro seems very useful, but I cannot see it documented >>>> in the https://imagej.nih.gov/ij/developer/macro/functions.html webpage? >>>> Are there any other Table.* functions implemented in ImageJ ? >>>> >>>> Stein >>>> >>>> -----Original Message----- >>>> From: ImageJ Interest Group [mailto:[hidden email]] On Behalf >>>> Of Michael Schmid >>>> Sent: 28. mars 2018 18:51 >>>> To: [hidden email] >>>> Subject: Re: How to create a customised results table and add data >>>> to it within a macro >>>> >>>> Hi Herbie & dschones, >>>> >>>> the first column with the 'Y123' etc. is the "row label", not a standard column. In a macro, you can get and set it with >>>> getResultLabel(row) and >>>> setResult("Label", row, string). >>>> >>>> With today's daily build (Help>Update ImageJ), you can also modify it without a loop over all rows: >>>> >>>> myName = "01.txt"; >>>> Table.applyMacro("Results", "_='"+myName+" '+_"); >>>> >>>> (Since the "row label" column has an empty name in this case, its >>>> name is mapped to an underscore as variable name.) >>>> >>>> This gives you a space, not a tab between the '01.txt' and the 'Y123' >>>> >>>> In principle, one could add a tab, but that would shift all columns to the right. The headers won't get shifted, and I don't think that one could also shift the headers. >>>> >>>> By the way, you can have Strings and numbers mixed in one column, but it won't help you here. E.g., if there is a column "X123", this works: >>>> setResult("X123", 1, "hello"); >>>> >>>> >>>> Michael >>>> ________________________________________________________________ -- 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 Wayne Rasband-2
Another request:
Table.reset(table) selects and clears an existing table; it would be useful to select an existing table without clearing it. Could a Table.select(table) function for doing this be added as well? We have a Table.save(filePath) command; Table.load(filePath) could also be useful. This would then create a new table based on the content of a file. I also wonder how to access tables that are not shown. The example macros you link to all uses commands that generate tables, e.g. run("List Elements"); How can I access tables that are not shown by default, e.g. the Histogram or LUT tables? Here is an example of something I often need to do, calculating cumulative histograms: run("Blobs (25K)"); run("Histogram"); //how can we now set the Histogram as active table? sumCumulative = 0; for (i=0; i<Table.size; i++) { v = Table.get("value", i); c = Table.get("count", i); sumCumulative += c; Table.set("cumulative", i, sumCumulative); } Table.update; Perhaps there could be a parameter to run("Histogram", "list") and run("Show LUT", "list") to show the corresponding tables you get when pressing the "List" button in these? Stein -----Original Message----- From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of Wayne Rasband Sent: 13. april 2018 00:26 To: [hidden email] Subject: Re: How to create a customised results table and add data to it within a macro > On Apr 12, 2018, at 7:31 AM, Stein Rørvik <[hidden email]> wrote: > > Thanks for this clarification. > I already suspected that the results columns order was hard-coded for compatibility. > > With the new Table.applyMacro function it will be easy to copy columns one by one, so one can append copied columns to the right of the table with new names in the desired order, and thereafter delete the old columns. This way one would get the desired layout without looping through all values. > > This example macro seems to work as intended: The latest daily build (1.52a47) adds a Table.renameColumn(oldName, newName) function. Here is an updated version of the example macro that uses it: run("Blobs (25K)"); run("Set Measurements...", "area mean centroid feret's"); setAutoThreshold("Default"); Table.reset("Results"); run("Analyze Particles...", "display include in_situ"); code = "FeretMinimum=MinFeret; FeretMaximum=Feret;" +"FeretAngleCopy=FeretAngle; FeretStartX=FeretX;" +"FeretStartY=FeretY"; Table.applyMacro(code); Table.deleteColumn("MinFeret"); Table.deleteColumn("Feret"); Table.deleteColumn("FeretAngle"); Table.deleteColumn("FeretX"); Table.deleteColumn("FeretY"); Table.renameColumn("FeretAngleCopy", "FeretAngle"); Table.update; The “Results” arguments in the original version are not needed since Table.reset("Results”) makes “Results” the current (active) table. All five columns are copied in one call to Table.applyMacro() since this is more efficient. The Table.update call is needed since Table.deleteColumn() and Table.renameColumn() do not update the display. Here is a list of the currently available Table.* functions: Table.create(table) - opens a new table Table.reset(table) - resets (clears) the table Table.size() - number of rows in the table Table.title() - title of the current table Table.headings() - column headings as a tab-delimited string Table.get(columnName, rowIndex) - returns a numeric value Table.getString(columnName, rowIndex) - returns a string value Table.set(columnName, rowIndex, value) - sets numeric or string value Table.update() - updates table window Table.applyMacro(macro) - applies macro code to table Table.rename(title1, title2) - renames a table Table.save(filePath) - saves the table Table.deleteRows(index1, index2) - deletes specified rows Table.renameColumn(oldName, newName) - renames a column Table.deleteColumn(columnName) - deletes specified column Table.showRowNumbers(boolean) - enable/disable row numbers And here are more example macros: http://wsr.imagej.net/macros/Sine_Cosine_Table2.txt http://wsr.imagej.net/macros/Make_Duplicate_Table.txt http://wsr.imagej.net/macros/Access_Plot_Data.txt http://wsr.imagej.net/macros/Access_Summary_Table.txt http://wsr.imagej.net/macros/Access_Overlay_Elements_Table.txt -wayne > > run("Blobs (25K)"); > run("Set Measurements...", "area mean standard modal min centroid > center perimeter bounding fit shape feret's stack display > redirect=None decimal=6"); setAutoThreshold("Default"); run("Analyze > Particles...", "display clear include in_situ"); > Table.applyMacro("FeretMinimum=MinFeret", "Results"); > Table.applyMacro("FeretMaximum=Feret", "Results"); > Table.applyMacro("FeretAngleCopy=FeretAngle", "Results"); > Table.applyMacro("FeretStartX=FeretX", "Results"); > Table.applyMacro("FeretStartY=FeretY", "Results"); > Table.deleteColumn("MinFeret", "Results"); Table.deleteColumn("Feret", > "Results"); Table.deleteColumn("FeretAngle", "Results"); > Table.deleteColumn("FeretX", "Results"); Table.deleteColumn("FeretY", > "Results"); > > in this context a new Table.renameColumn(oldName, newName, tableName) command could be useful? > For example, Table.renameColumn ("FeretAngleCopy", "FeretAngle", > "Results"); > > Stein > > -----Original Message----- > From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of > Michael Schmid > Sent: 10. april 2018 15:45 > To: [hidden email] > Subject: Re: How to create a customised results table and add data to > it within a macro > > Hi Stein, > > the standard headings of the ResultsTable are hardcoded. Unfortunately one cannot easily change this since it would break user plugins that access them by their number. This is also the reason for the non-intuitive ordering of the Feret items; "Feret" (min Feret diameter) was in ImageJ since the early days; the others were added later, when a few additional columns were already in between. > > (In principle this could be changed, but it would be some effort; it would require a translation table from the old numbers to the corresponding headings). > > Scaled Z: > Yes, you can have a macro for this like, e.g. > Table.applyMacro("x=0; y=0; Z=Slice-1; toScaled(x,y,Z);"); (It assumes that the current image window has the same calibration as the Results table; it also accounts for any offset of the origin in z direction). > > > Michael > ________________________________________________________________ > On 09/04/2018 22:32, Stein Rørvik wrote: >> Thank you for this clarification; I was not aware of this difference between string-based and numerical tables. >> >> Could it still make sense with a Table.setHeader(<tabdelimited string>) command for newly created numerical tables? >> >> This would then create an empty table with the desired column headers in the desired order; instead of new columns just appearing in an arbitrary order at first use. One thing that annoys me with the existing Results table is that there is no Z column for calibrated Z positions, and the Feret shape parameters are not placed in any logical order. If one could pre-set the column order, that would fix this easily. For example, MinFeret, Feret, FeretAngle, FeretX, FeretY. Also, Table.applyMacro("Z=Slice*<MicronsPerPixelZ>","Result") would easily add the missing Z coordinate column. >> >> Stein >> >> -----Original Message----- >> From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of >> Michael Schmid >> Sent: 09. april 2018 19:56 >> To: [hidden email] >> Subject: Re: How to create a customised results table and add data to >> it within a macro >> >> Hi Stein, >> >> a few remarks on tables: >> >> Beware that there are two different types of tables in ImageJ: >> >> (1) Tables like the ResultsTable, the one you get from Plots with "List", and tables with contents filled in by the new macro Table... >> commands are essentially numeric (there is a predefined "label" column, which must be the first one, this one is text-only). >> >> One can have non-numeric (String) values in other columns, then Table.get(colName, row) will give you NaN (not a number) and you need Table.getString(colName, row). But one would not do the for numbers; and applyMacro will work with the numeric value. >> >> For this type of tables, the column headers are fixed. The underlying data structure currently does not support renaming column headers. >> The column headers are simply created by assigning values to columns (by column name); if a column does not exist, it is created. >> >> (2) On the other hand, if you create a table by macro print commands, it is a pure list of Strings, with no numeric values behind it. You can't do any calculations with it, and the Table... commands don't work with it. The purpose of this type of table is only displaying values and saving or copying to the clipboard. >> >> >> This means that all commands using Strings like >> "Table.addRow(<tabdelimited string>)" for numeric tables would be >> problematic: It would require conversion of text to numbers; note >> that >> number>text>number conversion induces a loss of precision (unless the >> data are integer or the number of digits is very large). >> >> So it would be better to copy numeric values as such, not via String >> manipulation. >> >> >> Michael >> ________________________________________________________________ >> >> >> On 09/04/2018 17:07, Stein Rørvik wrote: >>> Thanks, exactly what I need. These functions will be very useful for manipulating an existing results table. >>> I already tried Table.applyMacro("Results", "DoubleArea=Area*2") with daily build 1.52a39 and it worked as expected. >>> >>> Today I use a similar approach as Timothy outlined: I create a new table, read the results from the old one, and use the getResult / setResult functions to create a new table. I also sometimes split lines and use the print(tablename, ... ) syntax to print tab-delimited headers and rows with the new table; this approach is much faster. >>> >>> To add to the below list, I think the functions >>> Table.setHeader(<tabdelimited string>) and >>> Table.addRow(<tabdelimited >>> string>), Table.updateRow(<rowindex>, <tabdelimited string>) would be useful for writing contents in batch. >>> >>> Also, perhaps Table.headings() could be complemented with >>> Table.rows() to return all the rows (except the header) as >>> tab-delimited strings concatenated by \n as well as Table.content() >>> to return everything as a string (headers plus all the rows) >>> >>> Stein >>> >>> -----Original Message----- >>> From: ImageJ Interest Group [mailto:[hidden email]] On Behalf >>> Of Michael Schmid >>> Sent: 09. april 2018 16:33 >>> To: [hidden email] >>> Subject: Re: How to create a customised results table and add data >>> to it within a macro >>> >>> Hi Stein, >>> >>> the Table.* functions are currently under development; they are in the daily build only. >>> >>> The list of currently implemented commands is in the Release notes: >>> https://github.com/imagej/imagej1/blob/master/release-notes.html >>> >>> Table.create() - opens a new table >>> Table.size() - number of rows in the table >>> Table.title() - title of the current table >>> Table.headings() - column headings as a tab-delimited string >>> Table.get(columnName, rowIndex) - returns a numeric value >>> Table.getString(columnName, rowIndex) - returns a string value >>> Table.set(columnName, rowIndex, value) - sets numeric or string value >>> Table.update() - updates table window >>> Table.reset() - resets (clears) the table >>> Table.applyMacro(macro) - applies macro code to table >>> Table.rename(title1, title2) - renames a table >>> Table.save(filePath) - saves the table >>> Table.deleteRows(index1, index2) - deletes specified rows >>> Table.deleteColumn(columnName) - deletes specified column >>> Table.hideRowNumbers() - disables display of row numbers >>> >>> >>> You can also specify the title of a table, this argument goes last. >>> >>> So e.g. the macro I had suggested last week has to be changed to: >>> myName = "01.txt"; >>> Table.applyMacro("_='"+myName+" '+_", "Results"); >>> >>> If no title is given, the commands refer the main "Results" table or to the current foreground window (if it has a table). >>> Inside the macro of 'apply macro', if no title is given, the Table commands refer to the table processed by the macro. >>> >>> Note that these commands are still experimental. Things may still change, so you may have to adapt your macros in case of changes! >>> >>> >>> Michael >>> ________________________________________________________________ >>> On 09/04/2018 12:43, Stein Rørvik wrote: >>>> Table.applyMacro seems very useful, but I cannot see it documented >>>> in the https://imagej.nih.gov/ij/developer/macro/functions.html webpage? >>>> Are there any other Table.* functions implemented in ImageJ ? >>>> >>>> Stein >>>> >>>> -----Original Message----- >>>> From: ImageJ Interest Group [mailto:[hidden email]] On Behalf >>>> Of Michael Schmid >>>> Sent: 28. mars 2018 18:51 >>>> To: [hidden email] >>>> Subject: Re: How to create a customised results table and add data >>>> to it within a macro >>>> >>>> Hi Herbie & dschones, >>>> >>>> the first column with the 'Y123' etc. is the "row label", not a standard column. In a macro, you can get and set it with >>>> getResultLabel(row) and >>>> setResult("Label", row, string). >>>> >>>> With today's daily build (Help>Update ImageJ), you can also modify it without a loop over all rows: >>>> >>>> myName = "01.txt"; >>>> Table.applyMacro("Results", "_='"+myName+" '+_"); >>>> >>>> (Since the "row label" column has an empty name in this case, its >>>> name is mapped to an underscore as variable name.) >>>> >>>> This gives you a space, not a tab between the '01.txt' and the 'Y123' >>>> >>>> In principle, one could add a tab, but that would shift all columns to the right. The headers won't get shifted, and I don't think that one could also shift the headers. >>>> >>>> By the way, you can have Strings and numbers mixed in one column, but it won't help you here. E.g., if there is a column "X123", this works: >>>> setResult("X123", 1, "hello"); >>>> >>>> >>>> Michael >>>> ________________________________________________________________ -- 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 Stein Rørvik
On 13/04/2018 09:43, Stein Rørvik wrote:
> I also wonder, in the code section of the macro, is the row number accessible as a predefined variable or function so that it can be used in the Table.applyMacro calculations? ________________________________________________________________ Hi Stein, the row number is a predefined variable, "row". If you have a table, right click it or use the Edit menu for the GUI version of 'apply macro'. The "Apply Macro" dialog has a "Help" button for more information. There is also a dropdown menu "Insert..." for variable names, where you also see how column names that are not valid variable names are mapped to variable names. For advanced users of 'aply macro', here is another example macro (for the 'apply macro' dialog or Table.applyMacrocommand), for smoothing a column (here "Y") by 3-point averages: col = "Y"; if(row>0 && row<Table.size()-1) Smoothed = (Table.get(col, rowIndex-1)+Table.get(col, row)+Table.get(col, row+1))/3; else Smoothed=NaN; [Note that the new column 'Smoothed' is created only if that variable is assigned when the macro is run for the first line. It would not be created without the 'else' clause] Michael ________________________________________________________________ On 13/04/2018 09:43, Stein Rørvik wrote: > Thank you! > > The new Table.applyMacro function makes it a lot easier to reorganize the results column-wise in bulk and create new columns with calculated data. Perhaps the below example macro or something similar could be uploaded to the macro directory of the website? > > I also wonder, in the code section of the macro, is the row number accessible as a predefined variable or function so that it can be used in the Table.applyMacro calculations? > > Stein > > -----Original Message----- > From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of Wayne Rasband > Sent: 13. april 2018 00:26 > To: [hidden email] > Subject: Re: How to create a customised results table and add data to it within a macro > >> On Apr 12, 2018, at 7:31 AM, Stein Rørvik <[hidden email]> wrote: >> >> Thanks for this clarification. >> I already suspected that the results columns order was hard-coded for compatibility. >> >> With the new Table.applyMacro function it will be easy to copy columns one by one, so one can append copied columns to the right of the table with new names in the desired order, and thereafter delete the old columns. This way one would get the desired layout without looping through all values. >> >> This example macro seems to work as intended: > > The latest daily build (1.52a47) adds a Table.renameColumn(oldName, newName) function. Here is an updated version of the example macro that uses it: > > run("Blobs (25K)"); > run("Set Measurements...", "area mean centroid feret's"); > setAutoThreshold("Default"); > Table.reset("Results"); > run("Analyze Particles...", "display include in_situ"); > code = "FeretMinimum=MinFeret; FeretMaximum=Feret;" > +"FeretAngleCopy=FeretAngle; FeretStartX=FeretX;" > +"FeretStartY=FeretY"; > Table.applyMacro(code); > Table.deleteColumn("MinFeret"); > Table.deleteColumn("Feret"); > Table.deleteColumn("FeretAngle"); > Table.deleteColumn("FeretX"); > Table.deleteColumn("FeretY"); > Table.renameColumn("FeretAngleCopy", "FeretAngle"); > Table.update; > > The “Results” arguments in the original version are not needed since Table.reset("Results”) makes “Results” the current (active) table. All five columns are copied in one call to Table.applyMacro() since this is more efficient. The Table.update call is needed since Table.deleteColumn() and Table.renameColumn() do not update the display. > > Here is a list of the currently available Table.* functions: > > Table.create(table) - opens a new table > Table.reset(table) - resets (clears) the table > Table.size() - number of rows in the table > Table.title() - title of the current table > Table.headings() - column headings as a tab-delimited string > Table.get(columnName, rowIndex) - returns a numeric value > Table.getString(columnName, rowIndex) - returns a string value > Table.set(columnName, rowIndex, value) - sets numeric or string value > Table.update() - updates table window > Table.applyMacro(macro) - applies macro code to table > Table.rename(title1, title2) - renames a table > Table.save(filePath) - saves the table > Table.deleteRows(index1, index2) - deletes specified rows > Table.renameColumn(oldName, newName) - renames a column > Table.deleteColumn(columnName) - deletes specified column > Table.showRowNumbers(boolean) - enable/disable row numbers > > And here are more example macros: > > http://wsr.imagej.net/macros/Sine_Cosine_Table2.txt > http://wsr.imagej.net/macros/Make_Duplicate_Table.txt > http://wsr.imagej.net/macros/Access_Plot_Data.txt > http://wsr.imagej.net/macros/Access_Summary_Table.txt > http://wsr.imagej.net/macros/Access_Overlay_Elements_Table.txt > > -wayne > > > > >> > >> run("Blobs (25K)"); >> run("Set Measurements...", "area mean standard modal min centroid >> center perimeter bounding fit shape feret's stack display >> redirect=None decimal=6"); setAutoThreshold("Default"); run("Analyze >> Particles...", "display clear include in_situ"); >> Table.applyMacro("FeretMinimum=MinFeret", "Results"); >> Table.applyMacro("FeretMaximum=Feret", "Results"); >> Table.applyMacro("FeretAngleCopy=FeretAngle", "Results"); >> Table.applyMacro("FeretStartX=FeretX", "Results"); >> Table.applyMacro("FeretStartY=FeretY", "Results"); >> Table.deleteColumn("MinFeret", "Results"); Table.deleteColumn("Feret", >> "Results"); Table.deleteColumn("FeretAngle", "Results"); >> Table.deleteColumn("FeretX", "Results"); Table.deleteColumn("FeretY", >> "Results"); >> >> in this context a new Table.renameColumn(oldName, newName, tableName) command could be useful? >> For example, Table.renameColumn ("FeretAngleCopy", "FeretAngle", >> "Results"); >> >> Stein >> >> -----Original Message----- >> From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of >> Michael Schmid >> Sent: 10. april 2018 15:45 >> To: [hidden email] >> Subject: Re: How to create a customised results table and add data to >> it within a macro >> >> Hi Stein, >> >> the standard headings of the ResultsTable are hardcoded. Unfortunately one cannot easily change this since it would break user plugins that access them by their number. This is also the reason for the non-intuitive ordering of the Feret items; "Feret" (min Feret diameter) was in ImageJ since the early days; the others were added later, when a few additional columns were already in between. >> >> (In principle this could be changed, but it would be some effort; it would require a translation table from the old numbers to the corresponding headings). >> >> Scaled Z: >> Yes, you can have a macro for this like, e.g. >> Table.applyMacro("x=0; y=0; Z=Slice-1; toScaled(x,y,Z);"); (It assumes that the current image window has the same calibration as the Results table; it also accounts for any offset of the origin in z direction). >> >> >> Michael >> ________________________________________________________________ >> On 09/04/2018 22:32, Stein Rørvik wrote: >>> Thank you for this clarification; I was not aware of this difference between string-based and numerical tables. >>> >>> Could it still make sense with a Table.setHeader(<tabdelimited string>) command for newly created numerical tables? >>> >>> This would then create an empty table with the desired column headers in the desired order; instead of new columns just appearing in an arbitrary order at first use. One thing that annoys me with the existing Results table is that there is no Z column for calibrated Z positions, and the Feret shape parameters are not placed in any logical order. If one could pre-set the column order, that would fix this easily. For example, MinFeret, Feret, FeretAngle, FeretX, FeretY. Also, Table.applyMacro("Z=Slice*<MicronsPerPixelZ>","Result") would easily add the missing Z coordinate column. >>> >>> Stein >>> >>> -----Original Message----- >>> From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of >>> Michael Schmid >>> Sent: 09. april 2018 19:56 >>> To: [hidden email] >>> Subject: Re: How to create a customised results table and add data to >>> it within a macro >>> >>> Hi Stein, >>> >>> a few remarks on tables: >>> >>> Beware that there are two different types of tables in ImageJ: >>> >>> (1) Tables like the ResultsTable, the one you get from Plots with "List", and tables with contents filled in by the new macro Table... >>> commands are essentially numeric (there is a predefined "label" column, which must be the first one, this one is text-only). >>> >>> One can have non-numeric (String) values in other columns, then Table.get(colName, row) will give you NaN (not a number) and you need Table.getString(colName, row). But one would not do the for numbers; and applyMacro will work with the numeric value. >>> >>> For this type of tables, the column headers are fixed. The underlying data structure currently does not support renaming column headers. >>> The column headers are simply created by assigning values to columns (by column name); if a column does not exist, it is created. >>> >>> (2) On the other hand, if you create a table by macro print commands, it is a pure list of Strings, with no numeric values behind it. You can't do any calculations with it, and the Table... commands don't work with it. The purpose of this type of table is only displaying values and saving or copying to the clipboard. >>> >>> >>> This means that all commands using Strings like >>> "Table.addRow(<tabdelimited string>)" for numeric tables would be >>> problematic: It would require conversion of text to numbers; note >>> that >>> number>text>number conversion induces a loss of precision (unless the >>> data are integer or the number of digits is very large). >>> >>> So it would be better to copy numeric values as such, not via String >>> manipulation. >>> >>> >>> Michael >>> ________________________________________________________________ >>> >>> >>> On 09/04/2018 17:07, Stein Rørvik wrote: >>>> Thanks, exactly what I need. These functions will be very useful for manipulating an existing results table. >>>> I already tried Table.applyMacro("Results", "DoubleArea=Area*2") with daily build 1.52a39 and it worked as expected. >>>> >>>> Today I use a similar approach as Timothy outlined: I create a new table, read the results from the old one, and use the getResult / setResult functions to create a new table. I also sometimes split lines and use the print(tablename, ... ) syntax to print tab-delimited headers and rows with the new table; this approach is much faster. >>>> >>>> To add to the below list, I think the functions >>>> Table.setHeader(<tabdelimited string>) and >>>> Table.addRow(<tabdelimited >>>> string>), Table.updateRow(<rowindex>, <tabdelimited string>) would be useful for writing contents in batch. >>>> >>>> Also, perhaps Table.headings() could be complemented with >>>> Table.rows() to return all the rows (except the header) as >>>> tab-delimited strings concatenated by \n as well as Table.content() >>>> to return everything as a string (headers plus all the rows) >>>> >>>> Stein >>>> >>>> -----Original Message----- >>>> From: ImageJ Interest Group [mailto:[hidden email]] On Behalf >>>> Of Michael Schmid >>>> Sent: 09. april 2018 16:33 >>>> To: [hidden email] >>>> Subject: Re: How to create a customised results table and add data >>>> to it within a macro >>>> >>>> Hi Stein, >>>> >>>> the Table.* functions are currently under development; they are in the daily build only. >>>> >>>> The list of currently implemented commands is in the Release notes: >>>> https://github.com/imagej/imagej1/blob/master/release-notes.html >>>> >>>> Table.create() - opens a new table >>>> Table.size() - number of rows in the table >>>> Table.title() - title of the current table >>>> Table.headings() - column headings as a tab-delimited string >>>> Table.get(columnName, rowIndex) - returns a numeric value >>>> Table.getString(columnName, rowIndex) - returns a string value >>>> Table.set(columnName, rowIndex, value) - sets numeric or string value >>>> Table.update() - updates table window >>>> Table.reset() - resets (clears) the table >>>> Table.applyMacro(macro) - applies macro code to table >>>> Table.rename(title1, title2) - renames a table >>>> Table.save(filePath) - saves the table >>>> Table.deleteRows(index1, index2) - deletes specified rows >>>> Table.deleteColumn(columnName) - deletes specified column >>>> Table.hideRowNumbers() - disables display of row numbers >>>> >>>> >>>> You can also specify the title of a table, this argument goes last. >>>> >>>> So e.g. the macro I had suggested last week has to be changed to: >>>> myName = "01.txt"; >>>> Table.applyMacro("_='"+myName+" '+_", "Results"); >>>> >>>> If no title is given, the commands refer the main "Results" table or to the current foreground window (if it has a table). >>>> Inside the macro of 'apply macro', if no title is given, the Table commands refer to the table processed by the macro. >>>> >>>> Note that these commands are still experimental. Things may still change, so you may have to adapt your macros in case of changes! >>>> >>>> >>>> Michael >>>> ________________________________________________________________ >>>> On 09/04/2018 12:43, Stein Rørvik wrote: >>>>> Table.applyMacro seems very useful, but I cannot see it documented >>>>> in the https://imagej.nih.gov/ij/developer/macro/functions.html webpage? >>>>> Are there any other Table.* functions implemented in ImageJ ? >>>>> >>>>> Stein >>>>> >>>>> -----Original Message----- >>>>> From: ImageJ Interest Group [mailto:[hidden email]] On Behalf >>>>> Of Michael Schmid >>>>> Sent: 28. mars 2018 18:51 >>>>> To: [hidden email] >>>>> Subject: Re: How to create a customised results table and add data >>>>> to it within a macro >>>>> >>>>> Hi Herbie & dschones, >>>>> >>>>> the first column with the 'Y123' etc. is the "row label", not a standard column. In a macro, you can get and set it with >>>>> getResultLabel(row) and >>>>> setResult("Label", row, string). >>>>> >>>>> With today's daily build (Help>Update ImageJ), you can also modify it without a loop over all rows: >>>>> >>>>> myName = "01.txt"; >>>>> Table.applyMacro("Results", "_='"+myName+" '+_"); >>>>> >>>>> (Since the "row label" column has an empty name in this case, its >>>>> name is mapped to an underscore as variable name.) >>>>> >>>>> This gives you a space, not a tab between the '01.txt' and the 'Y123' >>>>> >>>>> In principle, one could add a tab, but that would shift all columns to the right. The headers won't get shifted, and I don't think that one could also shift the headers. >>>>> >>>>> By the way, you can have Strings and numbers mixed in one column, but it won't help you here. E.g., if there is a column "X123", this works: >>>>> setResult("X123", 1, "hello"); >>>>> >>>>> >>>>> Michael >>>>> ________________________________________________________________ > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > > -- > 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 Stein Rørvik
On 13/04/2018 10:11, Stein Rørvik wrote:
> it would be useful to select an existing table without clearing it. > Could a Table.select(table) function for doing this be added as well? Hi Stein, I guess that selectWindow("name") would do the job. > We have a Table.save(filePath) command; > Table.load(filePath) could also be useful. > This would then create a new table based on the content of a file. Yes, I agree! It would be nice to have something like File>Import>Results, but without overwriting the Results table (maybe taking the file name as title) > I also wonder how to access tables that are not shown. > The example macros you link to all uses commands that generate tables, e.g. run("List Elements"); > How can I access tables that are not shown by default, e.g. the Histogram or LUT tables? Well, you can get the values as arrays via various macro functions: getLut(reds, greens, blues) returns 3 arrays getRawStatistics(nPixels, mean, min, max, std, histogram) getStatistics(area, mean, min, max, std, histogram) getHistogram(values, counts, nBins[, histMin, histMax]) Roi.getCoordinates(xpoints, ypoints) For plots, it is somewhat limited, however: Plot.getValues(xpoints, ypoints) does not give the full table if there are several curves or data sets (in contrast to the 'List' function). Michael -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Retrieving the values as arrays and populating the table from them would work, but it still requires that you make a loop and populate the cells one by one.
Perhaps we could have a Table.setArray(columnName, arrayName) function that would simply fill a column with the array values. The code for creating the histogram table would then be getHistogram(values, counts, nBins) Table.setArray("values", values) Table.setArray("counts", counts) Stein -----Original Message----- From: ImageJ Interest Group [mailto:[hidden email]] On Behalf Of Michael Schmid Sent: 13. april 2018 14:50 To: [hidden email] Subject: Re: How to create a customised results table and add data to it within a macro ... > The example macros you link to all uses commands that generate tables, > e.g. run("List Elements"); How can I access tables that are not shown by default, e.g. the Histogram or LUT tables? Well, you can get the values as arrays via various macro functions: getLut(reds, greens, blues) returns 3 arrays getRawStatistics(nPixels, mean, min, max, std, histogram) getStatistics(area, mean, min, max, std, histogram) getHistogram(values, counts, nBins[, histMin, histMax]) Roi.getCoordinates(xpoints, ypoints) For plots, it is somewhat limited, however: Plot.getValues(xpoints, ypoints) does not give the full table if there are several curves or data sets (in contrast to the 'List' function). Michael -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Free forum by Nabble | Edit this page |