Skip to content

Commit bf206c8

Browse files
committed
Reorder inputs before multiplications
This should be a stable order. Ideally this would be configurable to the user or tool auther, but for now this is based on the order within which data paramaters appear in tool.inputs, which depends on the order in the XML/YML. If this isn't stable the order of the input combinations may change, and elements will jump in the collection structure. For instance the reverse:forward output for a pair:pair in inputA multiplied by pair:pair in input B may end up in forward:reverse if re-run.
1 parent f5bd245 commit bf206c8

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

lib/galaxy/tools/parameters/meta.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
import copy
44
import itertools
55
import logging
6+
from collections import OrderedDict
67

78
from galaxy import (
89
exceptions,
910
model,
1011
util
1112
)
1213
from galaxy.util import permutations
14+
from . import visit_input_values
1315

1416
log = logging.getLogger(__name__)
1517

@@ -70,6 +72,28 @@ def expand_workflow_inputs(inputs):
7072
return params, params_keys
7173

7274

75+
def process_key(incoming_key, d):
76+
key_parts = incoming_key.split('|')
77+
if len(key_parts) == 1:
78+
# Regular parameter
79+
d[incoming_key] = object()
80+
elif key_parts[0].rsplit('_', maxsplit=1)[-1].isdigit():
81+
# Repeat
82+
input_name_index = key_parts[0].rsplit('_', maxsplit=1)
83+
input_name, index = input_name_index
84+
if input_name not in d:
85+
d[input_name] = []
86+
subdict = {}
87+
d[input_name].append(subdict)
88+
process_key("|".join(key_parts[1:]), d=subdict)
89+
else:
90+
# Section / Conditional
91+
input_name = key_parts[0]
92+
subdict = {}
93+
d[input_name] = subdict
94+
process_key("|".join(key_parts[1:]), d=subdict)
95+
96+
7397
def expand_meta_parameters(trans, tool, incoming):
7498
"""
7599
Take in a dictionary of raw incoming parameters and expand to a list
@@ -84,6 +108,25 @@ def expand_meta_parameters(trans, tool, incoming):
84108
for key in to_remove:
85109
incoming.pop(key)
86110

111+
# If we're going to multiply input dataset combinations
112+
# order matters, so the following reorders incoming
113+
# according to tool.inputs (which is ordered).
114+
incoming_copy = incoming.copy()
115+
nested_dict = {}
116+
for incoming_key in incoming_copy:
117+
if not incoming_key.startswith('__'):
118+
process_key(incoming_key, d=nested_dict)
119+
120+
reordered_incoming = OrderedDict()
121+
122+
def visitor(input, value, prefix, prefixed_name, prefixed_label, error, **kwargs):
123+
if prefixed_name in incoming_copy:
124+
reordered_incoming[prefixed_name] = incoming_copy[prefixed_name]
125+
del incoming_copy[prefixed_name]
126+
127+
visit_input_values(inputs=tool.inputs, input_values=nested_dict, callback=visitor)
128+
reordered_incoming.update(incoming_copy)
129+
87130
def classifier(input_key):
88131
value = incoming[input_key]
89132
if isinstance(value, dict) and 'values' in value:
@@ -111,7 +154,7 @@ def classifier(input_key):
111154

112155
# Stick an unexpanded version of multirun keys so they can be replaced,
113156
# by expand_mult_inputs.
114-
incoming_template = incoming.copy()
157+
incoming_template = reordered_incoming
115158

116159
expanded_incomings = permutations.expand_multi_inputs(incoming_template, classifier)
117160
if collections_to_match.has_collections():

lib/galaxy/util/permutations.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
Maybe this doesn't make sense and maybe much of this stuff could be replaced
77
with itertools product and permutations. These are open questions.
88
"""
9+
from collections import OrderedDict
10+
911
from galaxy.exceptions import MessageException
1012
from galaxy.util.bunch import Bunch
1113

@@ -40,9 +42,9 @@ def expand_multi_inputs(inputs, classifier, key_filter=None):
4042
def __split_inputs(inputs, classifier, key_filter):
4143
key_filter = key_filter or (lambda x: True)
4244

43-
single_inputs = {}
44-
matched_multi_inputs = {}
45-
multiplied_multi_inputs = {}
45+
single_inputs = OrderedDict()
46+
matched_multi_inputs = OrderedDict()
47+
multiplied_multi_inputs = OrderedDict()
4648

4749
for input_key in filter(key_filter, inputs):
4850
input_type, expanded_val = classifier(input_key)

0 commit comments

Comments
 (0)