Allow sorting collection elements based on file

Given a collection with element_identifiers:

```yml
element_1
element_2
```

we can arbitrarily re-order collection elements using a dataset
that specifies the new order, e.g

```
element_2
element_1
```

I think this nicely complements numeric and alphanumeric sorts that are
already possible with this tool.
This commit is contained in:
mvdbeek
2018-01-08 08:49:26 +01:00
parent cc18db4e49
commit 264b8680f3
3 changed files with 78 additions and 32 deletions
+17 -2
View File
@@ -9,6 +9,7 @@ import tarfile
import tempfile
import threading
from cgi import FieldStorage
from collections import OrderedDict
from datetime import datetime
from distutils.version import LooseVersion
from xml.etree import ElementTree
@@ -2497,14 +2498,28 @@ class SortTool(DatabaseOperationTool):
def produce_outputs(self, trans, out_data, output_collections, incoming, history):
hdca = incoming["input"]
sorttype = incoming["sort_type"]
sorttype = incoming["sort_type"]["sort_type"]
new_elements = odict()
elements = hdca.collection.elements
presort_elements = []
if sorttype == 'alpha':
presort_elements = [(dce.element_identifier, dce) for dce in elements]
elif sorttype == 'numeric':
presort_elements = [(int(re.sub('[^0-9]', '', dce.element_identifier)), dce) for dce in elements]
sorted_elements = [x[1] for x in sorted(presort_elements, key=lambda x: x[0])]
if presort_elements:
sorted_elements = [x[1] for x in sorted(presort_elements, key=lambda x: x[0])]
if sorttype == 'file':
hda = incoming["sort_type"]["sort_file"]
if hda.metadata and hda.metadata.get('data_lines', 0) == len(elements):
old_elements_dict = OrderedDict()
for element in elements:
old_elements_dict[element.element_identifier] = element
try:
sorted_elements = [old_elements_dict[line.strip()] for line in open(hda.file_name)]
except KeyError:
hdca_history_name = "%s: %s" (hdca.hid, hdca.name)
message = "List of element identifiers does not match element identifiers in collection '%s'" % hdca_history_name
raise Exception(message)
for dce in sorted_elements:
dce_object = dce.element_object
+59 -30
View File
@@ -8,10 +8,16 @@
class="ModelOperationToolAction"/>
<inputs>
<param type="data_collection" collection_type="list" name="input" label="Input Collection" />
<param type="select" name="sort_type" label="Sort collection identifiers" help="">
<option value="alpha">alphabetically</option>
<option value="numeric">numerically (strips all characters except numbers)</option>
</param>
<conditional name="sort_type">
<param type="select" name="sort_type" label="Sort collection identifiers" help="All element identifiers must be present once.">
<option value="alpha">alphabetically</option>
<option value="numeric">numerically (strips all characters except numbers)</option>
<option value="file">Sort collection using order of identifiers in text file</option>
</param>
<when value="file">
<param name="sort_file" type="data" format="txt" label="Select file that contains the new order of collection elements" help="Lines in text file must match collection"></param>
</when>
</conditional>
</inputs>
<outputs>
<collection name="output" format_source="input" type="list" label="${on_string} (sorted)" >
@@ -19,45 +25,68 @@
</outputs>
<tests>
<test>
<!-- test that we can reorder a collection using a file with element identifiers-->
<param name="input">
<collection type="list">
<element name="def" value="simple_line_alternative.txt" />
<element name="abc" value="simple_line.txt" />
<element name="element_1" value="simple_line_alternative.txt" />
<element name="element_2" value="simple_line.txt" />
</collection>
</param>
<param name="sort_type" value="alpha" />
<param name="sort_type" value="file"/>
<param name="sort_file" value="new_element_sort_order.txt"/>
<output_collection name="output" type="list">
<element name="abc">
<assert_contents>
<has_text_matching expression="^This is a line of text.\n$" />
</assert_contents>
</element>
<element name="def">
<assert_contents>
<has_text_matching expression="^This is a different line of text.\n$" />
</assert_contents>
</element>
<element name="element_2">
<assert_contents>
<has_text_matching expression="^This is a line of text.\n$" />
</assert_contents>
</element>
<element name="element_1">
<assert_contents>
<has_text_matching expression="^This is a different line of text.\n$" />
</assert_contents>
</element>
</output_collection>
</test>
<test>
<param name="input">
<collection type="list">
<element name="def0123400" value="simple_line_alternative.txt" />
<element name="abc5678" value="simple_line.txt" />
<element name="def" value="simple_line_alternative.txt" />
<element name="abc" value="simple_line.txt" />
</collection>
</param>
<param name="sort_type" value="numeric" />
<param name="sort_type" value="alpha" />
<output_collection name="output" type="list">
<element name="abc5678">
<assert_contents>
<has_text_matching expression="^This is a line of text.\n$" />
</assert_contents>
</element>
<element name="def0123400">
<assert_contents>
<has_text_matching expression="^This is a different line of text.\n$" />
</assert_contents>
</element>
<element name="abc">
<assert_contents>
<has_text_matching expression="^This is a line of text.\n$" />
</assert_contents>
</element>
<element name="def">
<assert_contents>
<has_text_matching expression="^This is a different line of text.\n$" />
</assert_contents>
</element>
</output_collection>
</test>
<test>
<param name="input">
<collection type="list">
<element name="def0123400" value="simple_line_alternative.txt" />
<element name="abc5678" value="simple_line.txt" />
</collection>
</param>
<param name="sort_type" value="numeric" />
<output_collection name="output" type="list">
<element name="abc5678">
<assert_contents>
<has_text_matching expression="^This is a line of text.\n$" />
</assert_contents>
</element>
<element name="def0123400">
<assert_contents>
<has_text_matching expression="^This is a different line of text.\n$" />
</assert_contents>
</element>
</output_collection>
</test>
</tests>
+2
View File
@@ -0,0 +1,2 @@
element_2
element_1