galaxy-dist commit 63db00b2f0a3: Enhance Tool Repeat Grouping parameter to allow specifying min, max, and default repeat unit counts.
# HG changeset patch -- Bitbucket.org # Project galaxy-dist # URL http://bitbucket.org/galaxy/galaxy-dist/overview # User Dan Blankenberg <dan@bx.psu.edu> # Date 1279124114 14400 # Node ID 63db00b2f0a3ef973666c81b8cd4934ad36c5317 # Parent 3a6b81352293854ff58970c19590ce14a218fb57 Enhance Tool Repeat Grouping parameter to allow specifying min, max, and default repeat unit counts. Bug Fix for when, under certain conditions, error messages were associated with the incorrect repeat unit. usage example: <repeat name="vcf_file" title="VCF population file" min="1" max="3" default="2"> <param format="tabular" name="vcf_input" type="data" label="VCF file"/> <param name="population_name" type="text" label="Name for this population" value=""/> </repeat> Remove previously unused "min" value specified in a single tool config (fastq_manipulation), to maintain existing behavior. Future Enhancement: Allow min/max/default values to be configured dynamically based upon other tool parameter values (e.g. similarly to dynamic options). --- a/tools/fastq/fastq_manipulation.xml +++ b/tools/fastq/fastq_manipulation.xml @@ -7,7 +7,7 @@ <page><param name="input_file" type="data" format="fastqsanger,fastqcssanger" label="FASTQ File" help="Requires groomed data: if your data does not appear here try using the FASTQ groomer."/><!-- Match Reads --> - <repeat name="match_blocks" title="Match Reads" min="1"> + <repeat name="match_blocks" title="Match Reads"><conditional name="match_type"><param name="match_type_selector" type="select" label="Match Reads by"><option value="identifier">Name/Identifier</option> @@ -47,7 +47,7 @@ </conditional></repeat><!-- Manipulate Matched Reads --> - <repeat name="manipulate_blocks" title="Manipulate Reads" min="1"> + <repeat name="manipulate_blocks" title="Manipulate Reads"><conditional name="manipulation_type"><param name="manipulation_type_selector" type="select" label="Manipulate Reads on"><option value="identifier">Name/Identifier</option> --- a/templates/tool_form.mako +++ b/templates/tool_form.mako @@ -91,6 +91,9 @@ function checkUncheckAll( name, check ) ${do_inputs( input.inputs, repeat_state[i], rep_errors, prefix + input.name + "_" + str(index) + "|", other_values )} <div class="form-row"><input type="submit" name="${prefix}${input.name}_${index}_remove" value="Remove ${input.title} ${i+1}"></div></div> + %if rep_errors.has_key( '__index__' ): + <div><img style="vertical-align: middle;" src="${h.url_for('/static/style/error_small.png')}"> <span style="vertical-align: middle;">${rep_errors['__index__']}</span></div> + %endif %endfor <div class="form-row"><input type="submit" name="${prefix}${input.name}_add" value="Add new ${input.title}"></div></div> --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -614,6 +614,11 @@ class Tool: group.name = elem.get( "name" ) group.title = elem.get( "title" ) group.inputs = self.parse_input_elem( elem, enctypes, context ) + group.default = int( elem.get( "default", 0 ) ) + group.min = int( elem.get( "min", 0 ) ) + group.max = float( elem.get( "max", "inf" ) ) #use float instead of int so that 'inf' can be used for no max + assert group.min <= group.max, ValueError( "Min repeat count must be less-than-or-equal to the max." ) + group.default = min( max( group.default, group.min ), group.max ) #force default to be within min-max range rval[group.name] = group elif elem.tag == "conditional": group = Conditional() @@ -914,7 +919,7 @@ class Tool: key = prefix + input.name if isinstance( input, Repeat ): group_state = state[input.name] - group_errors = [] + group_errors = [ {} for i in range( len( group_state ) ) ] #create list of empty errors for each previously existing state group_old_errors = old_errors.get( input.name, None ) any_group_errors = False # Check any removals before updating state -- only one @@ -922,10 +927,16 @@ class Tool: for i, rep_state in enumerate( group_state ): rep_index = rep_state['__index__'] if key + "_" + str(rep_index) + "_remove" in incoming: - del group_state[i] - if group_old_errors: - del group_old_errors[i] - break + if len( group_state ) > input.min: + del group_state[i] + del group_errors[i] + if group_old_errors: + del group_old_errors[i] + break + else: + group_errors[i] = { '__index__': 'Cannot remove repeat (min size=%i).' % input.min } + any_group_errors = True + break #only need to find one that can't be removed due to size, since only one removal is processed at a time anyway # Update state max_index = -1 for i, rep_state in enumerate( group_state ): @@ -947,17 +958,18 @@ class Tool: item_callback=item_callback ) if rep_errors: any_group_errors = True - group_errors.append( rep_errors ) - else: - group_errors.append( {} ) + group_errors[i].update( rep_errors ) # Check for addition if key + "_add" in incoming: - new_state = {} - new_state['__index__'] = max_index + 1 - self.fill_in_new_state( trans, input.inputs, new_state, context ) - group_state.append( new_state ) - if any_group_errors: + if len( group_state ) < input.max: + new_state = {} + new_state['__index__'] = max_index + 1 + self.fill_in_new_state( trans, input.inputs, new_state, context ) + group_state.append( new_state ) group_errors.append( {} ) + else: + group_errors[-1] = { '__index__': 'Cannot add repeat (max size=%i).' % input.max } + any_group_errors = True # Were there *any* errors for any repetition? if any_group_errors: errors[input.name] = group_errors --- a/lib/galaxy/tools/parameters/grouping.py +++ b/lib/galaxy/tools/parameters/grouping.py @@ -41,6 +41,9 @@ class Repeat( Group ): Group.__init__( self ) self.title = None self.inputs = None + self.default = 0 + self.min = None + self.max = None @property def title_plural( self ): if self.title.endswith( "s" ): @@ -87,7 +90,13 @@ class Repeat( Group ): else: input.visit_inputs( new_prefix, d[input.name], callback ) def get_initial_value( self, trans, context ): - return [] + rval = [] + for i in range( self.default ): + rval_dict = { '__index__': i} + for input in self.inputs.itervalues(): + rval_dict[ input.name ] = input.get_initial_value( trans, context ) + rval.append( rval_dict ) + return rval class UploadDataset( Group ): type = "upload_dataset"
participants (1)
-
commits-noreply@bitbucket.org