Question: Dynamic Tool Parameter Lists based on an Input File
0
gravatar for Bob
2.1 years ago by
Bob0
United States
Bob0 wrote:

What is the best way (or any way) to generate dynamic Galaxy tool fields based on data inside a selected data set file?

Part of our pipeline involves a JSON file containing a number of name/value pairs that we call our "model parameters". The name/value pairs are dynamically defined outside of Galaxy and show up in the JSON file that we import as our first data set in the pipeline.

Our current solution is to use a repeat block that contains a name and a value. The user must add a new block for each parameter and type in the name manually (along with the value). But the original name/value pairs are already in the input data set (JSON file). Is there any way to read that JSON file and then dynamically generate the named fields in the Galaxy interface?

I have already examined the following resources, but I'm not sure if they can do this:

Recursive Folder Checkbox Selection Tool
[https://biostar.usegalaxy.org/p/17209/#17260][1]

Dynamic Tool Parameter Lists?
[http://dev.list.galaxyproject.org/Dynamic-Tool-Parameter-Lists-td4175828.html][2]

Thanks in advance.

galaxy • 830 views
ADD COMMENTlink modified 2.0 years ago • written 2.1 years ago by Bob0
0
gravatar for Bob
2.0 years ago by
Bob0
United States
Bob0 wrote:

Maybe a concrete example would help?

We start with a JSON file as input (typically by uploading). Here's a simple example holding values of length, width, and height:

{
  "parameters":
    [
      {
        "par_name": "length", 
        "par_expression": "25",
        "par_units": "meters"
      },
      {
        "par_name": "width", 
        "par_expression": "5",
        "par_units": "meters"
      },
      {
        "par_name": "height", 
        "par_expression": "2",
        "par_units": "meters"
      }
    ]
}

We'd like to be able to change the "par_expression" values for parameters selected by "par_name". So a user might want to change "length" to 55, and "height" to 5 without changing "width". Of course, the name/value pairs in the JSON file vary from file to file, so we can't just hard-code those three names.

The only solution we've come up with so far requires the user to type in the name of the parameter along with the value. The name/value pairs are part of a "repeat" block, so the user can add as many parameter change blocks as they want. But they have to type in the name of each parameter (and get it right). We'd like to make the names selectable from a list rather than requiring them to be typed in manually. Any ideas?

Here's our current XML file ("modify_pars.xml"). The parameters are passed on the command line as "{name=value}" for relatively easy parsing.

<tool id="MOD_PARS1" name="Modify JSON Parameters" force_history_refresh="True" version="0.0.1">
  <description>Modify Parameters in a JSON File.</description>
  <command interpreter="python">
    modify_pars.py $json_input $json_output 
    #set eq = '='
    #for $par in $json_parameters:
      #set $par_val = str($par.par_name)+$eq+str($par.par_value)
      {$par_val}
    #end for
  </command>
  <inputs>
    <param format="json" name="json_input" type="data" label="JSON file to modify"/>
    <repeat name="json_parameters" title="Parameters to Modify">
        <param name="par_name" type="text" size="4" value="Par_Name" label="Parameter Name" />
        <param name="par_value" type="float" size="4" value="0" label="Parameter Value" />
    </repeat>
  </inputs>
  <outputs>
    <data format="json" name="json_output" />
  </outputs>
  <tests>
    <!--test>
    </test-->
  </tests>
  <help>
**This tool supports changing parameter values in a JSON file.**
  </help>
</tool>

Here's our current Python program ("modify_pars.py"):

#!/usr/bin/env python
import sys
import json

json_in_name = sys.argv[1]
json_out_name = sys.argv[2]

# Generate a dictionary of user parameter name/value pairs from command line input

user_mods = {}
for i in range(3,len(sys.argv)):
  user_par_assign = sys.argv[i].strip()
  if (user_par_assign[0] == '{') and (user_par_assign[-1] == '}') and (user_par_assign.count('=') == 1):
    # This fits the format for a parameter:  {name=value}
    par_name, par_val = user_par_assign[1:-1].split('=')
    user_mods[par_name] = par_val


# Open the JSON file and convert it to a Python dictionary
jsonf = open ( json_in_name, 'r' )
json_string = jsonf.read()
jsonf.close()

pd = json.loads ( json_string )

# Print for testing
print ( "Parameters before modification:" );
for par in pd['parameters']:
  print ( "  " + par['par_name'] + " = " + par['par_expression'] );

# Modify the parameters specified in the arguments

for par in pd['parameters']:
  if par['par_name'] in user_mods:
    par['par_expression'] = user_mods[par['par_name']]

# Print for testing
print ( "Parameters after modification:" );
for par in pd['parameters']:
  print ( "  " + par['par_name'] + " = " + par['par_expression'] );

# Convert the Python dictionary back to JSON and export it
jsonf = open ( json_out_name, 'w' )
jsonf.write ( json.dumps(pd) )
jsonf.close()

print ( "Finished modifications" )

Thanks in advance for any suggestions.

ADD COMMENTlink modified 2.0 years ago • written 2.0 years ago by Bob0
Please log in to add an answer.

Help
Access

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.
Powered by Biostar version 16.09
Traffic: 172 users visited in the last hour