Created
February 20, 2018 20:11
-
-
Save petebankhead/2ef44747f979607e23f50f278aeffd22 to your computer and use it in GitHub Desktop.
Script to combine the measurement tables exported by QuPath into a single text file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Script to combine results tables exported by QuPath. | |
| * | |
| * This is particularly intended to deal with the fact that results tables of annotations can produce results | |
| * with different column names, numbers and orders - making them awkward to combine later manually. | |
| * | |
| * It prompts for a directory containing exported text files, and then writes a new file in the same directory. | |
| * The name of the new file can be modified - see the first lines below. | |
| * | |
| * Note: This hasn't been tested very extensively - please check the results carefully, and report any problems so they | |
| * can be fixed! | |
| * | |
| * @author Pete Bankhead | |
| */ | |
| import qupath.lib.gui.QuPathGUI | |
| // Some parameters you might want to change... | |
| String ext = '.txt' // File extension to search for | |
| String delimiter = '\t' // Use tab-delimiter (this is for the *input*, not the output) | |
| String outputName = 'Combined_results.txt' // Name to use for output; use .csv if you really want comma separators | |
| // Prompt for directory containing the results | |
| def dirResults = QuPathGUI.getSharedDialogHelper().promptForDirectory() | |
| if (dirResults == null) | |
| return | |
| def fileResults = new File(dirResults, outputName) | |
| // Get a list of all the files to merge | |
| def files = dirResults.listFiles({ | |
| File f -> f.isFile() && | |
| f.getName().toLowerCase().endsWith(ext) && | |
| f.getName() != outputName} as FileFilter) | |
| if (files.size() <= 1) { | |
| print 'At least two results files needed to merge!' | |
| return | |
| } else | |
| print 'Will try to merge ' + files.size() + ' files' | |
| // Represent final results as a 'list of maps' | |
| def results = new ArrayList<Map<String, String>>() | |
| // Store all column names that we see - not all files necessarily have all columns | |
| def allColumns = new LinkedHashSet<String>() | |
| allColumns.add('File name') | |
| // Loop through the files | |
| for (file in files) { | |
| // Check if we have anything to read | |
| def lines = file.readLines() | |
| if (lines.size() <= 1) { | |
| print 'No results found in ' + file | |
| continue | |
| } | |
| // Get the header columns | |
| def iter = lines.iterator() | |
| def columns = iter.next().split(delimiter) | |
| allColumns.addAll(columns) | |
| // Create the entries | |
| while (iter.hasNext()) { | |
| def line = iter.next() | |
| if (line.isEmpty()) | |
| continue | |
| def map = ['File name': file.getName()] | |
| def values = line.split(delimiter) | |
| // Check if we have the expected number of columns | |
| if (values.size() != columns.size()) { | |
| print String.format('Number of entries (%d) does not match the number of columns (%d)!', columns.size(), values.size()) | |
| print('I will stop processing ' + file.getName()) | |
| break | |
| } | |
| // Store the results | |
| for (int i = 0; i < columns.size(); i++) | |
| map[columns[i]] = values[i] | |
| results.add(map) | |
| } | |
| } | |
| // Create a new results file - using a comma delimiter if the extension is csv | |
| if (outputName.toLowerCase().endsWith('.csv')) | |
| delimiter = ',' | |
| int count = 0 | |
| fileResults.withPrintWriter { | |
| def header = String.join(delimiter, allColumns) | |
| it.println(header) | |
| // Add each of the results, with blank columns for missing values | |
| for (result in results) { | |
| for (column in allColumns) { | |
| it.print(result.getOrDefault(column, '')) | |
| it.print(delimiter) | |
| } | |
| it.println() | |
| count++ | |
| } | |
| } | |
| // Success! Hopefully... | |
| print 'Done! ' + count + ' result(s) written to ' + fileResults.getAbsolutePath() |
powersas88
commented
Jun 13, 2019
via email
I got it. I'm super new and have taught myself from the ground up using
Qupath. I didn't know you could leave in the whole script. I was going
through and deleting the statements //…..
Thank you so much. I really did try and took hours trying to figure out
what I was doing wrong.
…On Thu, Jun 13, 2019 at 2:29 AM Pete ***@***.***> wrote:
@powersas88 <https://github.com/powersas88> I've no idea... the error
reports an issue with fileResults not existing at line 49, but fileResults
isn't used around line 49 in my script - and anyway it should already have
been defined at line 27. So it looks like the script you're running differs
in some way...?
I'd need to see exactly the script you run from the script editor to be
able to help further.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<https://gist.github.com/2ef44747f979607e23f50f278aeffd22?email_source=notifications&email_token=AMI2BDQ46EFLXVVME5ST6JDP2HSK7A5CNFSM4HXV34O2YY3PNVWWK3TUL52HS4DFVNDWS43UINXW23LFNZ2KUY3PNVWWK3TUL5UWJTQAFTS2U#gistcomment-2942378>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AMI2BDR5HGD2RQBKBMR5QKLP2HSK7ANCNFSM4HXV34OQ>
.
--
*Astin *P*owers, **MD*
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment