From bdbd21f250cd11e4e68cb23065e4506fff41729a Mon Sep 17 00:00:00 2001 From: Aysam Guerler Date: Fri, 8 Mar 2013 11:52:37 -0500 Subject: [PATCH 1/3] sort: preserves comments in sorted output --- tools/filters/sorter.py | 76 +++++++++------- tools/filters/sorter.xml | 187 ++++++++++++--------------------------- 2 files changed, 102 insertions(+), 161 deletions(-) diff --git a/tools/filters/sorter.py b/tools/filters/sorter.py index c74c0d71b3c..4b64b4710e0 100644 --- a/tools/filters/sorter.py +++ b/tools/filters/sorter.py @@ -1,49 +1,59 @@ """ -Sorts tabular data on one or more columns. - -usage: %prog [options] - -i, --input=i: Tabular file to be sorted - -o, --out_file1=o: Sorted output file - -c, --column=c: First column to sort on - -s, --style=s: Sort style (numerical or alphabetical) - -r, --order=r: Order (ASC or DESC) - -usage: %prog input out_file1 column style order [column style ...] + Sorts tabular data on one or more columns. All comments of the file are collected + and placed at the beginning of the sorted output file. + + usage: sorter.py [options] + -i, --input: Tabular file to be sorted + -o, --output: Sorted output file + -k, --key: Key (see manual for bash/sort) + + usage: sorter.py input output [key ...] """ +# 03/05/2013 guerler +# imports import os, re, string, sys -from galaxy import eggs -import pkg_resources; pkg_resources.require( "bx-python" ) -from bx.cookbook import doc_optparse +from optparse import OptionParser +# error def stop_err( msg ): sys.stderr.write( "%s\n" % msg ) sys.exit() +# main def main(): - #Parse Command Line - options, args = doc_optparse.parse( __doc__ ) - try: - inputfile = options.input - outputfile = '-o %s' % options.out_file1 - columns = [options.column] - styles = [('','n')[options.style == 'num']] - orders = [('','r')[options.order == 'DESC']] - col_style_orders = sys.argv[6:] - if len(col_style_orders) > 1: - columns.extend([col_style_orders[i] for i in range(0,len(col_style_orders),3)]) - styles.extend([('','n')[col_style_orders[i] == 'num'] for i in range(1,len(col_style_orders),3)]) - orders.extend([('','r')[col_style_orders[i] == 'DESC'] for i in range(2,len(col_style_orders),3)]) - cols = [ '-k%s,%s%s%s'%(columns[i], columns[i], styles[i], orders[i]) for i in range(len(columns)) ] - except Exception, ex: - stop_err('Error parsing input parameters\n' + str(ex)) + # define options + parser = OptionParser() + parser.add_option("-i", "--input") + parser.add_option("-o", "--output") + parser.add_option("-k", "--key", action="append") - # Launch sort. - cmd = "sort -f -t ' ' %s %s %s" % (' '.join(cols), outputfile, inputfile) + # parse + options, args = parser.parse_args() + try: - os.system(cmd) + # retrieve options + input = options.input + output = options.output + key = ["-k" + k for k in options.key] + + # grep comments + grep_comments = "(grep '^#' %s) > %s" % (input, output) + print grep_comments + + # grep and sort columns + sort_columns = "(grep '^[^#]' %s | sort -f -t '\t' %s) >> %s" % (input, ' '.join(key), output) + print sort_columns + + # execute + os.system(grep_comments) + os.system(sort_columns) + except Exception, ex: - stop_err('Error running sort command\n' + str(ex)) + stop_err('Error running sorter.py\n' + str(ex)) + + # exit + sys.exit(0) if __name__ == "__main__": main() diff --git a/tools/filters/sorter.xml b/tools/filters/sorter.xml index e2fed1a4bae..0e6275333a8 100644 --- a/tools/filters/sorter.xml +++ b/tools/filters/sorter.xml @@ -1,130 +1,61 @@ - - data in ascending or descending order - - sorter.py - --input=$input - --out_file1=$out_file1 - --column=$column - --style=$style - --order=$order - #for $col in $column_set: - ${col.other_column} - ${col.other_style} - ${col.other_order} - #end for - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + data in ascending or descending order + + sorter.py + --input=$input + --output=$output + --key=$column,$column$style$order + #for $col in $column_set: + --key=${col.other_column},${col.other_column}${col.other_style}${col.other_order} + #end for + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -.. class:: infomark - -**TIP:** If your data is not TAB delimited, use *Text Manipulation->Convert* - ------ - -**Syntax** - -This tool sorts the dataset on any number of columns in either ascending or descending order. - -* Numerical sort orders numbers by their magnitude, ignores all characters besides numbers, and evaluates a string of numbers to the value they signify. -* Alphabetical sort is a phonebook type sort based on the conventional order of letters in an alphabet. Each nth letter is compared with the nth letter of other words in the list, starting at the first letter of each word and advancing to the second, third, fourth, and so on, until the order is established. Therefore, in an alphabetical sort, 2 comes after 100 (1 < 2). - ------ - -**Examples** - -The list of numbers 4,17,3,5 collates to 3,4,5,17 by numerical sorting, while it collates to 17,3,4,5 by alphabetical sorting. - -Sorting the following:: - - Q d 7 II jhu 45 - A kk 4 I h 111 - Pd p 1 ktY WS 113 - A g 10 H ZZ 856 - A edf 4 tw b 234 - BBB rt 10 H ZZ 100 - A rew 10 d b 1111 - C sd 19 YH aa 10 - Hah c 23 ver bb 467 - MN gtr 1 a X 32 - N j 9 a T 205 - BBB rrf 10 b Z 134 - odfr ws 6 Weg dew 201 - C f 3 WW SW 34 - A jhg 4 I b 345 - Pd gf 7 Gthe de 567 - rS hty 90 YY LOp 89 - A g 10 H h 43 - A g 4 I h 500 - -on columns 1 (alpha), 3 (num), and 6 (num) in ascending order will yield:: - - A kk 4 I h 111 - A edf 4 tw b 234 - A jhg 4 I b 345 - A g 4 I h 500 - A g 10 H h 43 - A g 10 H ZZ 856 - A rew 10 d b 1111 - BBB rt 10 H ZZ 100 - BBB rrf 10 b Z 134 - C f 3 WW SW 34 - C sd 19 YH aa 10 - Hah c 23 ver bb 467 - MN gtr 1 a X 32 - N j 9 a T 205 - odfr ws 6 Weg dew 201 - Pd p 1 ktY WS 113 - Pd gf 7 Gthe de 567 - Q d 7 II jhu 45 - rS hty 90 YY LOp 89 - - From 8cd17848ad960e52682a865c710bf7d5fad3e48a Mon Sep 17 00:00:00 2001 From: Aysam Guerler Date: Fri, 8 Mar 2013 12:10:19 -0500 Subject: [PATCH 2/3] sort: update log to browser --- tools/filters/sorter.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/filters/sorter.py b/tools/filters/sorter.py index 4b64b4710e0..fdc8e994875 100644 --- a/tools/filters/sorter.py +++ b/tools/filters/sorter.py @@ -35,15 +35,15 @@ def main(): # retrieve options input = options.input output = options.output - key = ["-k" + k for k in options.key] + key = [" -k" + k for k in options.key] # grep comments grep_comments = "(grep '^#' %s) > %s" % (input, output) - print grep_comments + #print grep_comments # grep and sort columns sort_columns = "(grep '^[^#]' %s | sort -f -t '\t' %s) >> %s" % (input, ' '.join(key), output) - print sort_columns + #print sort_columns # execute os.system(grep_comments) From 5d5895326eb8335c3db5f4958288f45af718070f Mon Sep 17 00:00:00 2001 From: Dannon Baker Date: Fri, 8 Mar 2013 12:29:52 -0500 Subject: [PATCH 3/3] Remove import * from tool_runner, fixes rerun (missing visit_input_values function) after recent import refactoring. --- .../webapps/galaxy/controllers/tool_runner.py | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/lib/galaxy/webapps/galaxy/controllers/tool_runner.py b/lib/galaxy/webapps/galaxy/controllers/tool_runner.py index 7f38dc75637..aa2e2083a70 100644 --- a/lib/galaxy/webapps/galaxy/controllers/tool_runner.py +++ b/lib/galaxy/webapps/galaxy/controllers/tool_runner.py @@ -2,15 +2,20 @@ Upload class """ -from galaxy.web.base.controller import * +import logging +import galaxy.util + +from galaxy import web +from galaxy.tools import DefaultToolState +from galaxy.tools.actions import upload_common +from galaxy.tools.parameters import params_to_incoming, visit_input_values +from galaxy.tools.parameters.basic import DataToolParameter, UnvalidatedValue from galaxy.util.bunch import Bunch from galaxy.util.hash_util import is_hashable -from galaxy.tools import DefaultToolState -from galaxy.tools.parameters.basic import UnvalidatedValue -from galaxy.tools.parameters import params_to_incoming -from galaxy.tools.actions import upload_common +from galaxy.web import error, url_for +from galaxy.web.base.controller import BaseUIController +from galaxy.web.form_builder import SelectField -import logging log = logging.getLogger( __name__ ) class AddFrameData: @@ -47,7 +52,7 @@ class ToolRunner( BaseUIController ): tools = [] tool = None # Backwards compatibility for datasource tools that have default tool_id configured, but which are now using only GALAXY_URL. - tool_ids = util.listify( tool_id ) + tool_ids = galaxy.util.listify( tool_id ) for tool_id in tool_ids: if get_loaded_tools_by_lineage: tools = toolbox.get_loaded_tools_by_lineage( tool_id ) @@ -83,7 +88,7 @@ class ToolRunner( BaseUIController ): message=message, status=status, redirect=redirect ) ) - params = util.Params( kwd, sanitize = False ) #Sanitize parameters when substituting into command line via input wrappers + params = galaxy.util.Params( kwd, sanitize = False ) #Sanitize parameters when substituting into command line via input wrappers #do param translation here, used by datasource tools if tool.input_translator: tool.input_translator.translate( params ) @@ -103,7 +108,7 @@ class ToolRunner( BaseUIController ): toolbox=self.get_toolbox(), tool_version_select_field=tool_version_select_field, tool=tool, - util=util, + util=galaxy.util, add_frame=add_frame, **vars ) @@ -215,7 +220,7 @@ class ToolRunner( BaseUIController ): #create an incoming object from the original job's dataset-modified param objects incoming = {} params_to_incoming( incoming, tool.inputs, params_objects, trans.app ) - incoming[ "tool_state" ] = util.object_to_string( state.encode( tool, trans.app ) ) + incoming[ "tool_state" ] = galaxy.util.object_to_string( state.encode( tool, trans.app ) ) template, vars = tool.handle_input( trans, incoming, old_errors=upgrade_messages ) #update new state with old parameters # Is the "add frame" stuff neccesary here? add_frame = AddFrameData() @@ -228,7 +233,7 @@ class ToolRunner( BaseUIController ): toolbox=self.get_toolbox(), tool_version_select_field=tool_version_select_field, tool=tool, - util=util, + util=galaxy.util, add_frame=add_frame, tool_id_version_message=tool_id_version_message, **vars ) @@ -288,9 +293,9 @@ class ToolRunner( BaseUIController ): tool = self.get_toolbox().get_tool( tool_id ) if not tool: return False # bad tool_id - nonfile_params = util.Params( kwd, sanitize=False ) + nonfile_params = galaxy.util.Params( kwd, sanitize=False ) if kwd.get( 'tool_state', None ) not in ( None, 'None' ): - encoded_state = util.string_to_object( kwd["tool_state"] ) + encoded_state = galaxy.util.string_to_object( kwd["tool_state"] ) tool_state = DefaultToolState() tool_state.decode( encoded_state, tool, trans.app ) else: