diff --git a/lib/galaxy/dataset_collections/matching.py b/lib/galaxy/dataset_collections/matching.py index 7230916a5d4..cccf08661aa 100644 --- a/lib/galaxy/dataset_collections/matching.py +++ b/lib/galaxy/dataset_collections/matching.py @@ -75,7 +75,7 @@ class MatchingCollections( object ): return None matching_collections = MatchingCollections() - for input_key, to_match in collections_to_match.items(): + for input_key, to_match in sorted(collections_to_match.items()): hdca = to_match.hdca collection_type_description = collection_type_descriptions.for_collection_type( hdca.collection.collection_type ) subcollection_type = to_match.subcollection_type diff --git a/lib/galaxy/tools/execute.py b/lib/galaxy/tools/execute.py index c926e5d09e1..0751555133e 100644 --- a/lib/galaxy/tools/execute.py +++ b/lib/galaxy/tools/execute.py @@ -157,7 +157,21 @@ class ToolExecutionTracker( object ): log.warning( "Problem matching up datasets while attempting to create implicit dataset collections") continue output = self.tool.outputs[ output_name ] - element_identifiers = structure.element_identifiers_for_outputs( trans, outputs ) + + element_identifiers = None + if hasattr(output, "default_identifier_source"): + # Switch the structure for outputs if the output specified a default_identifier_source + collection_type_descriptions = trans.app.dataset_collections_service.collection_type_descriptions + + source_collection = self.collection_info.collections.get(output.default_identifier_source) + if source_collection: + collection_type_description = collection_type_descriptions.for_collection_type(source_collection.collection.collection_type) + _structure = structure.for_dataset_collection( source_collection.collection, collection_type_description=collection_type_description) + if structure.can_match(_structure): + element_identifiers = _structure.element_identifiers_for_outputs(trans, outputs) + + if not element_identifiers: + element_identifiers = structure.element_identifiers_for_outputs( trans, outputs ) implicit_collection_info = dict( implicit_inputs=implicit_inputs, diff --git a/lib/galaxy/tools/parser/xml.py b/lib/galaxy/tools/parser/xml.py index 00e9d0eee08..cad49bb39a6 100644 --- a/lib/galaxy/tools/parser/xml.py +++ b/lib/galaxy/tools/parser/xml.py @@ -289,6 +289,7 @@ class XmlToolSource(ToolSource): output.format = output_format output.change_format = data_elem.findall("change_format") output.format_source = data_elem.get("format_source", default_format_source) + output.default_identifier_source = data_elem.get("default_identifier_source", 'None') output.metadata_source = data_elem.get("metadata_source", default_metadata_source) output.parent = data_elem.get("parent", None) output.label = xml_text( data_elem, "label" ) diff --git a/lib/galaxy/tools/parser/yaml.py b/lib/galaxy/tools/parser/yaml.py index 4450fb8f6d0..d45e9f4e478 100644 --- a/lib/galaxy/tools/parser/yaml.py +++ b/lib/galaxy/tools/parser/yaml.py @@ -113,6 +113,7 @@ class YamlToolSource(ToolSource): output.format = output_dict.get("format", "data") output.change_format = [] output.format_source = output_dict.get("format_source", None) + output.default_identifier_source = output_dict.get("default_identifier_source", None) output.metadata_source = output_dict.get("metadata_source", "") output.parent = output_dict.get("parent", None) output.label = output_dict.get( "label", None ) diff --git a/lib/galaxy/tools/xsd/galaxy.xsd b/lib/galaxy/tools/xsd/galaxy.xsd index 3d7bc3ef7a1..0abeed028e0 100644 --- a/lib/galaxy/tools/xsd/galaxy.xsd +++ b/lib/galaxy/tools/xsd/galaxy.xsd @@ -3693,6 +3693,12 @@ The valid values for format can be found in This sets the data type of the output file to be the same format as that of a tool input dataset. + + + Sets the source of element identifier to the specified input. +This only applies to collections that are mapped over a non-collection input and that have equivalent structures. + + This copies the metadata information diff --git a/test/api/test_tools.py b/test/api/test_tools.py index 4605ed7883e..e40b68b9b3f 100644 --- a/test/api/test_tools.py +++ b/test/api/test_tools.py @@ -1059,6 +1059,20 @@ class ToolsTestCase( api.ApiTestCase ): self.assertEquals( len( response_object[ 'jobs' ] ), 2 ) self.assertEquals( len( response_object[ 'implicit_collections' ] ), 1 ) + @skip_without_tool( "identifier_source" ) + def test_default_identifier_source_map_over(self): + history_id = self.dataset_populator.new_history() + input_a_hdca_id = self.dataset_collection_populator.create_list_in_history( history_id, contents=[("A", "A content")]).json()['id'] + input_b_hdca_id = self.dataset_collection_populator.create_list_in_history(history_id, contents=[("B", "B content")]).json()['id'] + inputs = { + "inputA": { 'batch': True, 'values': [ dict( src="hdca", id=input_a_hdca_id ) ] }, + "inputB": { 'batch': True, 'values': [ dict( src="hdca", id=input_b_hdca_id ) ] }, + } + self.dataset_populator.wait_for_history( history_id, assert_ok=True ) + create = self._run("identifier_source", history_id, inputs, assert_ok=True) + assert create['implicit_collections'][0]['elements'][0]['element_identifier'] == 'B' + assert create['implicit_collections'][1]['elements'][0]['element_identifier'] == 'A' + @skip_without_tool( "collection_creates_pair" ) def test_map_over_collection_output( self ): history_id = self.dataset_populator.new_history() diff --git a/test/functional/tools/samples_tool_conf.xml b/test/functional/tools/samples_tool_conf.xml index 4197eb61b5f..c4285378ca5 100644 --- a/test/functional/tools/samples_tool_conf.xml +++ b/test/functional/tools/samples_tool_conf.xml @@ -78,6 +78,7 @@ +