diff --git a/config/tool_conf.xml.sample b/config/tool_conf.xml.sample
index 3e19d92f265..b8b98a82d77 100644
--- a/config/tool_conf.xml.sample
+++ b/config/tool_conf.xml.sample
@@ -36,6 +36,8 @@
+
+
diff --git a/lib/galaxy/tools/__init__.py b/lib/galaxy/tools/__init__.py
index b84709615f6..686c4e6e8a5 100755
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -2506,11 +2506,98 @@ class FlattenTool( DatabaseOperationTool ):
)
+class RelabelFromFileTool(DatabaseOperationTool):
+ tool_type = 'relabel_from_file'
+
+ def produce_outputs(self, trans, out_data, output_collections, incoming, history):
+ hdca = incoming["input"]
+ how_type = incoming["how"]["how_select"]
+ new_labels_dataset_assoc = incoming["how"]["labels"]
+ strict = string_as_bool(incoming["how"]["strict"])
+ new_elements = odict()
+
+ def add_copied_value_to_new_elements(new_label, dce_object):
+ new_label = new_label.strip()
+ if new_label in new_elements:
+ raise Exception("New identifier [%s] appears twice in resulting collection, these values must be unique." % new_label)
+ copied_value = dce_object.copy()
+ if getattr(copied_value, "history_content_type", None) == "dataset":
+ history.add_dataset(copied_value, set_hid=False)
+ new_elements[new_label] = copied_value
+
+ new_labels_path = new_labels_dataset_assoc.file_name
+ new_labels = open(new_labels_path, "r").readlines(1024 * 1000000)
+ if strict and len(hdca.collection.elements) != len(new_labels):
+ raise Exception("Relabel mapping file contains incorrect number of identifiers")
+ if how_type == "tabular":
+ # We have a tabular file, where the first column is an existing element identifier,
+ # and the second column is the new element identifier.
+ source_new_label = (line.strip().split('\t') for line in new_labels)
+ new_labels_dict = {source: new_label for source, new_label in source_new_label}
+ for i, dce in enumerate(hdca.collection.elements):
+ dce_object = dce.element_object
+ element_identifier = dce.element_identifier
+ default = element_identifier if strict else None
+ new_label = new_labels_dict.get(element_identifier, default)
+ if not new_label:
+ raise Exception("Failed to find new label for identifier [%s]" % element_identifier)
+ add_copied_value_to_new_elements(new_label, dce_object)
+ else:
+ # If new_labels_dataset_assoc is not a two-column tabular dataset we label with the current line of the dataset
+ for i, dce in enumerate(hdca.collection.elements):
+ dce_object = dce.element_object
+ add_copied_value_to_new_elements(new_labels[i], dce_object)
+ for key in new_elements.keys():
+ if not re.match("^[\w\-_]+$", key):
+ raise Exception("Invalid new colleciton identifier [%s]" % key)
+ output_collections.create_collection(
+ next(iter(self.outputs.values())), "output", elements=new_elements
+ )
+
+
+class FilterFromFileTool(DatabaseOperationTool):
+ tool_type = 'filter_from_file'
+
+ def produce_outputs(self, trans, out_data, output_collections, incoming, history):
+ hdca = incoming["input"]
+ how_filter = incoming["how"]["how_filter"]
+ filter_dataset_assoc = incoming["how"]["filter_source"]
+ filtered_elements = odict()
+ discarded_elements = odict()
+
+ filtered_path = filter_dataset_assoc.file_name
+ filtered_identifiers_raw = open(filtered_path, "r").readlines(1024 * 1000000)
+ filtered_identifiers = [i.strip() for i in filtered_identifiers_raw]
+
+ # If filtered_dataset_assoc is not a two-column tabular dataset we label with the current line of the dataset
+ for i, dce in enumerate(hdca.collection.elements):
+ dce_object = dce.element_object
+ element_identifier = dce.element_identifier
+ in_filter_file = element_identifier in filtered_identifiers
+ passes_filter = in_filter_file if how_filter == "remove_if_absent" else not in_filter_file
+
+ copied_value = dce_object.copy()
+ if getattr(copied_value, "history_content_type", None) == "dataset":
+ history.add_dataset(copied_value, set_hid=False)
+
+ if passes_filter:
+ filtered_elements[element_identifier] = copied_value
+ else:
+ discarded_elements[element_identifier] = copied_value
+
+ output_collections.create_collection(
+ self.outputs["output_filtered"], "output_filtered", elements=filtered_elements
+ )
+ output_collections.create_collection(
+ self.outputs["output_discarded"], "output_discarded", elements=discarded_elements
+ )
+
+
# Populate tool_type to ToolClass mappings
tool_types = {}
for tool_class in [ Tool, SetMetadataTool, OutputParameterJSONTool,
DataManagerTool, DataSourceTool, AsyncDataSourceTool,
- UnzipCollectionTool, ZipCollectionTool, MergeCollectionTool,
+ UnzipCollectionTool, ZipCollectionTool, MergeCollectionTool, RelabelFromFileTool, FilterFromFileTool,
DataDestinationTool ]:
tool_types[ tool_class.tool_type ] = tool_class
diff --git a/lib/galaxy/tools/filter_from_file.xml b/lib/galaxy/tools/filter_from_file.xml
new file mode 100644
index 00000000000..6dbb28277a4
--- /dev/null
+++ b/lib/galaxy/tools/filter_from_file.xml
@@ -0,0 +1,91 @@
+
+ from contents of a file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/galaxy/tools/relabel_from_file.xml b/lib/galaxy/tools/relabel_from_file.xml
new file mode 100644
index 00000000000..797e647819a
--- /dev/null
+++ b/lib/galaxy/tools/relabel_from_file.xml
@@ -0,0 +1,152 @@
+
+ from contents of a file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test-data/filter_labels_1.txt b/test-data/filter_labels_1.txt
new file mode 100644
index 00000000000..928f40b2d21
--- /dev/null
+++ b/test-data/filter_labels_1.txt
@@ -0,0 +1 @@
+i2
diff --git a/test-data/new_labels_1.txt b/test-data/new_labels_1.txt
new file mode 100644
index 00000000000..3fe0afa80c6
--- /dev/null
+++ b/test-data/new_labels_1.txt
@@ -0,0 +1 @@
+new_i1
\ No newline at end of file
diff --git a/test-data/new_labels_2.txt b/test-data/new_labels_2.txt
new file mode 100644
index 00000000000..7f11cbd1aaf
--- /dev/null
+++ b/test-data/new_labels_2.txt
@@ -0,0 +1 @@
+i1 new_i1
diff --git a/test-data/new_labels_bad_1.txt b/test-data/new_labels_bad_1.txt
new file mode 100644
index 00000000000..5177cef38e0
--- /dev/null
+++ b/test-data/new_labels_bad_1.txt
@@ -0,0 +1 @@
+new_i; rm -rf
\ No newline at end of file
diff --git a/test-data/new_labels_bad_2.txt b/test-data/new_labels_bad_2.txt
new file mode 100644
index 00000000000..591022662d7
--- /dev/null
+++ b/test-data/new_labels_bad_2.txt
@@ -0,0 +1,2 @@
+newi1
+newi1
\ No newline at end of file
diff --git a/test/functional/tools/samples_tool_conf.xml b/test/functional/tools/samples_tool_conf.xml
index 59f76c37d1d..415766d0603 100644
--- a/test/functional/tools/samples_tool_conf.xml
+++ b/test/functional/tools/samples_tool_conf.xml
@@ -146,5 +146,7 @@
+
+