From 57281890853c0920362bdaeee2f9beb29d1af399 Mon Sep 17 00:00:00 2001 From: Helena Rasche Date: Fri, 30 Oct 2020 10:25:14 +0100 Subject: [PATCH 1/9] Implement simple edam toolbox using non-readable ids --- doc/source/admin/galaxy_options.rst | 11 ++++ lib/galaxy/config/sample/galaxy.yml.sample | 4 ++ lib/galaxy/tools/toolbox/base.py | 64 ++++++++++++++++++++- lib/galaxy/webapps/galaxy/config_schema.yml | 8 +++ 4 files changed, 85 insertions(+), 2 deletions(-) diff --git a/doc/source/admin/galaxy_options.rst b/doc/source/admin/galaxy_options.rst index 57101a4e65f8..a588be2bcd3b 100644 --- a/doc/source/admin/galaxy_options.rst +++ b/doc/source/admin/galaxy_options.rst @@ -3180,6 +3180,17 @@ :Type: bool +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``enable_beta_edam_toolbox`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:Description: + Enable beta EDAM organised toolbox which ignores admin managed + sections in lieu of EDAM topics only. +:Default: ``false`` +:Type: bool + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``default_workflow_export_format`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/galaxy/config/sample/galaxy.yml.sample b/lib/galaxy/config/sample/galaxy.yml.sample index ac4d64b02ee1..204dda67fb3f 100644 --- a/lib/galaxy/config/sample/galaxy.yml.sample +++ b/lib/galaxy/config/sample/galaxy.yml.sample @@ -1589,6 +1589,10 @@ galaxy: # workflows built using these modules may not function in the future.) #enable_beta_workflow_modules: false + # Enable beta EDAM organised toolbox which ignores admin managed + # sections in lieu of EDAM topics only. + #enable_beta_edam_toolbox: false + # Default format for the export of workflows. Possible values are 'ga' # or 'format2'. #default_workflow_export_format: ga diff --git a/lib/galaxy/tools/toolbox/base.py b/lib/galaxy/tools/toolbox/base.py index 8f6f6b0ad88c..ceb655a036c7 100644 --- a/lib/galaxy/tools/toolbox/base.py +++ b/lib/galaxy/tools/toolbox/base.py @@ -112,7 +112,10 @@ def __init__(self, config_filenames, tool_root_dir, app, save_integrated_tool_pa self._init_tools_from_configs(config_filenames) if self.app.name == 'galaxy' and self._integrated_tool_panel_config_has_contents: # Load self._tool_panel based on the order in self._integrated_tool_panel. - self._load_tool_panel() + if self.app.config.enable_beta_edam_toolbox: + self._load_tool_panel_edam() + else: + self._load_tool_panel() if save_integrated_tool_panel: self._save_integrated_tool_panel() @@ -397,6 +400,60 @@ def __add_tool_to_tool_panel(self, tool, panel_component, section=False): if log_msg and (not hasattr(self.app, 'tool_cache') or tool_id in self.app.tool_cache._new_tool_ids): log.debug(log_msg) + def _get_edam_sec(self, tool): + edam = tool.edam_operations + tool.edam_topics + if len(edam) > 0: + # TODO nicer edam names. + sec_id, sec_nm = edam[0], edam[0] + else: + sec_id, sec_nm = 'uncategorized', 'Uncategorized' + return sec_id, sec_nm + + def _get_section(self, val): + sec_id, sec_nm = self._get_edam_sec(val) + if sec_id not in self._tool_panel: + section = ToolSection({'id': sec_id, 'name': sec_nm, 'version': ''}) + self._tool_panel[sec_id] = section + else: + section = self._tool_panel[sec_id] + return section + + def _load_tool_panel_edam(self): + execution_timer = ExecutionTimer() + for key, item_type, val in self._integrated_tool_panel.panel_items_iter(): + if item_type == panel_item_types.TOOL: + tool_id = key.replace('tool_', '', 1) + if tool_id in self._tools_by_id: + section = self._get_section(val) + + if tool_id in self._tools_by_id: + self.__add_tool_to_tool_panel(val, section, section=True) + self._integrated_section_by_tool[tool_id] = key, val.name + elif item_type == panel_item_types.WORKFLOW: + workflow_id = key.replace('workflow_', '', 1) + if workflow_id in self._workflows_by_id: + workflow = self._workflows_by_id[workflow_id] + self._tool_panel[key] = workflow + log.debug(f"Loaded workflow: {workflow_id} {workflow.name}") + elif item_type == panel_item_types.SECTION: + for section_key, section_item_type, section_val in val.panel_items_iter(): + if section_item_type == panel_item_types.TOOL: + tool_id = section_key.replace('tool_', '', 1) + if tool_id in self._tools_by_id: + section = self._get_section(section_val) + + self.__add_tool_to_tool_panel(section_val, section, section=True) + self._integrated_section_by_tool[tool_id] = key, val.name + + elif section_item_type == panel_item_types.WORKFLOW: + workflow_id = section_key.replace('workflow_', '', 1) + if workflow_id in self._workflows_by_id: + workflow = self._workflows_by_id[workflow_id] + section.elems[section_key] = workflow + log.debug(f"Loaded workflow: {workflow_id} {workflow.name}") + log.debug("Loading tool panel finished %s", execution_timer) + + def _load_tool_panel(self): execution_timer = ExecutionTimer() for key, item_type, val in self._integrated_tool_panel.panel_items_iter(): @@ -823,7 +880,10 @@ def quick_load(tool_file, async_load=True): integrated_elems[key] = tool if async_load: - self._load_tool_panel() + if self.app.config.enable_beta_edam_toolbox: + self._load_tool_panel_edam() + else: + self._load_tool_panel() self._save_integrated_tool_panel() return tool.id except Exception: diff --git a/lib/galaxy/webapps/galaxy/config_schema.yml b/lib/galaxy/webapps/galaxy/config_schema.yml index a80ac907741f..e948431fc227 100644 --- a/lib/galaxy/webapps/galaxy/config_schema.yml +++ b/lib/galaxy/webapps/galaxy/config_schema.yml @@ -2323,6 +2323,14 @@ mapping: stable API. (The module state definitions may change and workflows built using these modules may not function in the future.) + enable_beta_edam_toolbox: + type: bool + default: false + required: false + desc: | + Enable beta EDAM organised toolbox which ignores admin managed + sections in lieu of EDAM topics only. + default_workflow_export_format: type: str default: ga From 1733f462dd198b5b06355c165565db1dfb6d7d01 Mon Sep 17 00:00:00 2001 From: Helena Rasche Date: Fri, 30 Oct 2020 10:33:34 +0100 Subject: [PATCH 2/9] Parse EDAM ontology to decode names --- doc/source/admin/galaxy_options.rst | 12 ++++++++++++ lib/galaxy/config/sample/galaxy.yml.sample | 5 +++++ lib/galaxy/tools/toolbox/base.py | 13 ++++++++++++- lib/galaxy/webapps/galaxy/config_schema.yml | 10 +++++++++- 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/doc/source/admin/galaxy_options.rst b/doc/source/admin/galaxy_options.rst index a588be2bcd3b..addbd412d479 100644 --- a/doc/source/admin/galaxy_options.rst +++ b/doc/source/admin/galaxy_options.rst @@ -3191,6 +3191,18 @@ :Type: bool +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``beta_edam_toolbox_ontology_path`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:Description: + Sets the path to EDAM ontology file. + The value of this option will be resolved with respect to + . +:Default: ``EDAM_1.23.tsv`` +:Type: str + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``default_workflow_export_format`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/galaxy/config/sample/galaxy.yml.sample b/lib/galaxy/config/sample/galaxy.yml.sample index 204dda67fb3f..d6f97346182c 100644 --- a/lib/galaxy/config/sample/galaxy.yml.sample +++ b/lib/galaxy/config/sample/galaxy.yml.sample @@ -1593,6 +1593,11 @@ galaxy: # sections in lieu of EDAM topics only. #enable_beta_edam_toolbox: false + # Sets the path to EDAM ontology file. + # The value of this option will be resolved with respect to + # . + #beta_edam_toolbox_ontology_path: EDAM_1.23.tsv + # Default format for the export of workflows. Possible values are 'ga' # or 'format2'. #default_workflow_export_format: ga diff --git a/lib/galaxy/tools/toolbox/base.py b/lib/galaxy/tools/toolbox/base.py index ceb655a036c7..82f805815da1 100644 --- a/lib/galaxy/tools/toolbox/base.py +++ b/lib/galaxy/tools/toolbox/base.py @@ -110,6 +110,17 @@ def __init__(self, config_filenames, tool_root_dir, app, save_integrated_tool_pa self._filter_factory = FilterFactory(self) self._tool_tag_manager = tool_tag_manager(app) self._init_tools_from_configs(config_filenames) + + if self.app.config.enable_beta_edam_toolbox: + with open(self.app.config.beta_edam_toolbox_ontology_path, 'r') as handle: + self.edam = {} + for idx, line in enumerate(handle.readlines()): + fields = line.split('\t') + if not fields[0].startswith('http://edamontology.org/'): + continue + term_id = fields[0][len('http://edamontology.org/'):] + self.edam[term_id] = fields[1] # preferred label + if self.app.name == 'galaxy' and self._integrated_tool_panel_config_has_contents: # Load self._tool_panel based on the order in self._integrated_tool_panel. if self.app.config.enable_beta_edam_toolbox: @@ -404,7 +415,7 @@ def _get_edam_sec(self, tool): edam = tool.edam_operations + tool.edam_topics if len(edam) > 0: # TODO nicer edam names. - sec_id, sec_nm = edam[0], edam[0] + sec_id, sec_nm = edam[0], self.edam.get(edam[0], 'New term') else: sec_id, sec_nm = 'uncategorized', 'Uncategorized' return sec_id, sec_nm diff --git a/lib/galaxy/webapps/galaxy/config_schema.yml b/lib/galaxy/webapps/galaxy/config_schema.yml index e948431fc227..29c19ab9a3de 100644 --- a/lib/galaxy/webapps/galaxy/config_schema.yml +++ b/lib/galaxy/webapps/galaxy/config_schema.yml @@ -486,7 +486,7 @@ mapping: file_sources_config_file: type: str - default: file_sources_conf.yml + default: file_sources_conf.yml path_resolves_to: config_dir required: false desc: | @@ -2331,6 +2331,14 @@ mapping: Enable beta EDAM organised toolbox which ignores admin managed sections in lieu of EDAM topics only. + beta_edam_toolbox_ontology_path: + type: str + default: EDAM_1.23.tsv + path_resolves_to: config_dir + required: false + desc: | + Sets the path to EDAM ontology file. + default_workflow_export_format: type: str default: ga From ab64d8f5547d09a66a0b02f0fcd6bd82694fbd3a Mon Sep 17 00:00:00 2001 From: Helena Rasche Date: Fri, 30 Oct 2020 10:57:52 +0100 Subject: [PATCH 3/9] linting --- lib/galaxy/tools/toolbox/base.py | 37 +++++++++++++++----------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/lib/galaxy/tools/toolbox/base.py b/lib/galaxy/tools/toolbox/base.py index 82f805815da1..e33ccf32c554 100644 --- a/lib/galaxy/tools/toolbox/base.py +++ b/lib/galaxy/tools/toolbox/base.py @@ -119,7 +119,7 @@ def __init__(self, config_filenames, tool_root_dir, app, save_integrated_tool_pa if not fields[0].startswith('http://edamontology.org/'): continue term_id = fields[0][len('http://edamontology.org/'):] - self.edam[term_id] = fields[1] # preferred label + self.edam[term_id] = fields[1] # preferred label if self.app.name == 'galaxy' and self._integrated_tool_panel_config_has_contents: # Load self._tool_panel based on the order in self._integrated_tool_panel. @@ -415,19 +415,19 @@ def _get_edam_sec(self, tool): edam = tool.edam_operations + tool.edam_topics if len(edam) > 0: # TODO nicer edam names. - sec_id, sec_nm = edam[0], self.edam.get(edam[0], 'New term') + for term in edam: + yield term, self.edam.get(term, 'Unknown EDAM Term') else: - sec_id, sec_nm = 'uncategorized', 'Uncategorized' - return sec_id, sec_nm + yield 'uncategorized', 'Uncategorized' def _get_section(self, val): - sec_id, sec_nm = self._get_edam_sec(val) - if sec_id not in self._tool_panel: - section = ToolSection({'id': sec_id, 'name': sec_nm, 'version': ''}) - self._tool_panel[sec_id] = section - else: - section = self._tool_panel[sec_id] - return section + for sec_id, sec_nm in self._get_edam_sec(val): + if sec_id not in self._tool_panel: + section = ToolSection({'id': sec_id, 'name': sec_nm, 'version': ''}) + self._tool_panel[sec_id] = section + else: + section = self._tool_panel[sec_id] + yield section def _load_tool_panel_edam(self): execution_timer = ExecutionTimer() @@ -435,11 +435,10 @@ def _load_tool_panel_edam(self): if item_type == panel_item_types.TOOL: tool_id = key.replace('tool_', '', 1) if tool_id in self._tools_by_id: - section = self._get_section(val) - if tool_id in self._tools_by_id: - self.__add_tool_to_tool_panel(val, section, section=True) - self._integrated_section_by_tool[tool_id] = key, val.name + for section in self._get_section(val): + self.__add_tool_to_tool_panel(val, section, section=True) + self._integrated_section_by_tool[tool_id] = key, val.name elif item_type == panel_item_types.WORKFLOW: workflow_id = key.replace('workflow_', '', 1) if workflow_id in self._workflows_by_id: @@ -451,10 +450,9 @@ def _load_tool_panel_edam(self): if section_item_type == panel_item_types.TOOL: tool_id = section_key.replace('tool_', '', 1) if tool_id in self._tools_by_id: - section = self._get_section(section_val) - - self.__add_tool_to_tool_panel(section_val, section, section=True) - self._integrated_section_by_tool[tool_id] = key, val.name + for section in self._get_section(section_val): + self.__add_tool_to_tool_panel(section_val, section, section=True) + self._integrated_section_by_tool[tool_id] = key, val.name elif section_item_type == panel_item_types.WORKFLOW: workflow_id = section_key.replace('workflow_', '', 1) @@ -464,7 +462,6 @@ def _load_tool_panel_edam(self): log.debug(f"Loaded workflow: {workflow_id} {workflow.name}") log.debug("Loading tool panel finished %s", execution_timer) - def _load_tool_panel(self): execution_timer = ExecutionTimer() for key, item_type, val in self._integrated_tool_panel.panel_items_iter(): From f86cd33e6d6945a2b874692810524afed9cfb318 Mon Sep 17 00:00:00 2001 From: Helena Rasche Date: Fri, 30 Oct 2020 11:31:06 +0100 Subject: [PATCH 4/9] Update lib/galaxy/webapps/galaxy/config_schema.yml Co-authored-by: Marius van den Beek --- lib/galaxy/webapps/galaxy/config_schema.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/galaxy/webapps/galaxy/config_schema.yml b/lib/galaxy/webapps/galaxy/config_schema.yml index 29c19ab9a3de..a778dc4a208a 100644 --- a/lib/galaxy/webapps/galaxy/config_schema.yml +++ b/lib/galaxy/webapps/galaxy/config_schema.yml @@ -2334,11 +2334,17 @@ mapping: beta_edam_toolbox_ontology_path: type: str default: EDAM_1.23.tsv - path_resolves_to: config_dir + path_resolves_to: data_dir required: false desc: | Sets the path to EDAM ontology file. + beta_edam_ontology_url: + type: str + default: + required: false + desc: | + Sets the url to the EDAM ontology file. default_workflow_export_format: type: str default: ga From 646b133bb36add65edd8436575248953bebbfda9 Mon Sep 17 00:00:00 2001 From: Helena Rasche Date: Fri, 30 Oct 2020 11:31:28 +0100 Subject: [PATCH 5/9] Add EDAM topics to unannotated tools --- doc/source/admin/galaxy_options.rst | 12 +- lib/galaxy/config/sample/galaxy.yml.sample | 5 +- lib/galaxy/tools/apply_rules.xml | 8 +- lib/galaxy/tools/build_list.xml | 3 + lib/galaxy/tools/data_fetch.xml | 3 + lib/galaxy/tools/extract_dataset.xml | 5 +- lib/galaxy/tools/filter_empty_collection.xml | 3 + lib/galaxy/tools/filter_failed_collection.xml | 3 + lib/galaxy/tools/filter_from_file.xml | 9 +- lib/galaxy/tools/flatten_collection.xml | 3 + lib/galaxy/tools/merge_collection.xml | 27 +-- lib/galaxy/tools/relabel_from_file.xml | 9 +- lib/galaxy/tools/sort_collection_list.xml | 3 + lib/galaxy/tools/tag_collection_from_file.xml | 3 + lib/galaxy/tools/toolbox/base.py | 172 +++++++++++++++--- lib/galaxy/tools/unzip_collection.xml | 5 +- lib/galaxy/tools/zip_collection.xml | 5 +- lib/galaxy/webapps/galaxy/config_schema.yml | 3 +- tools/data_source/biomart.xml | 3 + tools/data_source/biomart_test.xml | 3 + tools/data_source/cbi_rice_mart.xml | 3 + tools/data_source/ebi_sra.xml | 3 + tools/data_source/eupathdb.xml | 5 +- tools/data_source/fly_modencode.xml | 5 +- tools/data_source/flymine.xml | 5 +- tools/data_source/flymine_test.xml | 5 +- tools/data_source/genbank.xml | 3 + tools/data_source/gramene_mart.xml | 5 +- tools/data_source/hapmapmart.xml | 3 + tools/data_source/hbvar.xml | 3 + tools/data_source/import.xml | 3 + tools/data_source/intermine.xml | 5 +- tools/data_source/metabolicmine.xml | 5 +- tools/data_source/microbial_import.xml | 3 + tools/data_source/modmine.xml | 5 +- tools/data_source/mousemine.xml | 5 +- tools/data_source/ratmine.xml | 5 +- tools/data_source/sra.xml | 3 + tools/data_source/ucsc_tablebrowser.xml | 3 + .../data_source/ucsc_tablebrowser_archaea.xml | 3 + tools/data_source/ucsc_tablebrowser_test.xml | 3 + tools/data_source/upload.xml | 3 + tools/data_source/worm_modencode.xml | 5 +- tools/data_source/wormbase.xml | 5 +- tools/data_source/wormbase_test.xml | 5 +- tools/data_source/yeastmine.xml | 5 +- tools/data_source/zebrafishmine.xml | 5 +- tools/filters/axt_to_concat_fasta.xml | 2 +- tools/filters/catWrapper.xml | 3 + tools/filters/commWrapper.xml | 5 +- tools/filters/compare.xml | 7 +- tools/filters/cutWrapper.xml | 3 + tools/filters/fileGrep.xml | 5 +- tools/filters/fixedValueColumn.xml | 7 +- tools/filters/grep.xml | 13 +- tools/filters/headWrapper.xml | 3 + 56 files changed, 366 insertions(+), 80 deletions(-) diff --git a/doc/source/admin/galaxy_options.rst b/doc/source/admin/galaxy_options.rst index addbd412d479..4ef30366b0a8 100644 --- a/doc/source/admin/galaxy_options.rst +++ b/doc/source/admin/galaxy_options.rst @@ -3198,11 +3198,21 @@ :Description: Sets the path to EDAM ontology file. The value of this option will be resolved with respect to - . + . :Default: ``EDAM_1.23.tsv`` :Type: str +~~~~~~~~~~~~~~~~~~~~~~~~~~ +``beta_edam_ontology_url`` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:Description: + Sets the url to the EDAM ontology file. +:Default: ``https://edamontology.org/EDAM_1.23.tsv`` +:Type: str + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``default_workflow_export_format`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/galaxy/config/sample/galaxy.yml.sample b/lib/galaxy/config/sample/galaxy.yml.sample index d6f97346182c..235b7db883e2 100644 --- a/lib/galaxy/config/sample/galaxy.yml.sample +++ b/lib/galaxy/config/sample/galaxy.yml.sample @@ -1595,9 +1595,12 @@ galaxy: # Sets the path to EDAM ontology file. # The value of this option will be resolved with respect to - # . + # . #beta_edam_toolbox_ontology_path: EDAM_1.23.tsv + # Sets the url to the EDAM ontology file. + #beta_edam_ontology_url: https://edamontology.org/EDAM_1.23.tsv + # Default format for the export of workflows. Possible values are 'ga' # or 'format2'. #default_workflow_export_format: ga diff --git a/lib/galaxy/tools/apply_rules.xml b/lib/galaxy/tools/apply_rules.xml index eb31edc48a3b..4d8adade3e23 100644 --- a/lib/galaxy/tools/apply_rules.xml +++ b/lib/galaxy/tools/apply_rules.xml @@ -3,6 +3,10 @@ version="1.1.0" tool_type="apply_rules_to_collection"> + + operation_2409 + operation_3695 + @@ -15,14 +19,14 @@ + + operation_2409 + diff --git a/lib/galaxy/tools/data_fetch.xml b/lib/galaxy/tools/data_fetch.xml index 5ebe6ea5e57b..2a7b722f8a11 100644 --- a/lib/galaxy/tools/data_fetch.xml +++ b/lib/galaxy/tools/data_fetch.xml @@ -4,6 +4,9 @@ workflow_compatible="false" profile="18.01"> + + operation_0224 + + + operation_3695 + @@ -13,7 +16,7 @@ - + diff --git a/lib/galaxy/tools/filter_empty_collection.xml b/lib/galaxy/tools/filter_empty_collection.xml index 149be6125577..3e7bf8714e34 100644 --- a/lib/galaxy/tools/filter_empty_collection.xml +++ b/lib/galaxy/tools/filter_empty_collection.xml @@ -6,6 +6,9 @@ + + operation_3695 + diff --git a/lib/galaxy/tools/filter_failed_collection.xml b/lib/galaxy/tools/filter_failed_collection.xml index b28444b4d12b..bc486175bf57 100644 --- a/lib/galaxy/tools/filter_failed_collection.xml +++ b/lib/galaxy/tools/filter_failed_collection.xml @@ -6,6 +6,9 @@ + + operation_3695 + diff --git a/lib/galaxy/tools/filter_from_file.xml b/lib/galaxy/tools/filter_from_file.xml index defcba391478..83f53400491e 100644 --- a/lib/galaxy/tools/filter_from_file.xml +++ b/lib/galaxy/tools/filter_from_file.xml @@ -6,6 +6,9 @@ + + operation_3695 + @@ -78,13 +81,13 @@ + + operation_2409 + diff --git a/lib/galaxy/tools/merge_collection.xml b/lib/galaxy/tools/merge_collection.xml index 28ce818a8e5f..05737c055763 100644 --- a/lib/galaxy/tools/merge_collection.xml +++ b/lib/galaxy/tools/merge_collection.xml @@ -6,6 +6,9 @@ + + operation_2409 + @@ -63,7 +66,7 @@ - + @@ -93,7 +96,7 @@ - + @@ -105,7 +108,7 @@ - + @@ -125,7 +128,7 @@ - + @@ -137,7 +140,7 @@ - + @@ -160,7 +163,7 @@ - + @@ -175,7 +178,7 @@ - + @@ -190,7 +193,7 @@ - + @@ -203,7 +206,7 @@ - + @@ -217,7 +220,7 @@ - + @@ -229,7 +232,7 @@ - + @@ -273,7 +276,7 @@ + + operation_3096 + @@ -133,7 +136,7 @@ + + operation_3802 + diff --git a/lib/galaxy/tools/tag_collection_from_file.xml b/lib/galaxy/tools/tag_collection_from_file.xml index 2abad0f54526..47b1f8b1fe16 100644 --- a/lib/galaxy/tools/tag_collection_from_file.xml +++ b/lib/galaxy/tools/tag_collection_from_file.xml @@ -6,6 +6,9 @@ + + operation_3096 + diff --git a/lib/galaxy/tools/toolbox/base.py b/lib/galaxy/tools/toolbox/base.py index e33ccf32c554..902d86f2e80e 100644 --- a/lib/galaxy/tools/toolbox/base.py +++ b/lib/galaxy/tools/toolbox/base.py @@ -9,9 +9,11 @@ ) from errno import ENOENT from urllib.parse import urlparse +import urllib.request from markupsafe import escape +from galaxy.datatypes import sniff from galaxy.exceptions import ( ConfigurationError, MessageException, @@ -25,6 +27,7 @@ from galaxy.util import ( etree, ExecutionTimer, + get_charset_from_http_headers, listify, parse_xml, string_as_bool, @@ -110,16 +113,7 @@ def __init__(self, config_filenames, tool_root_dir, app, save_integrated_tool_pa self._filter_factory = FilterFactory(self) self._tool_tag_manager = tool_tag_manager(app) self._init_tools_from_configs(config_filenames) - - if self.app.config.enable_beta_edam_toolbox: - with open(self.app.config.beta_edam_toolbox_ontology_path, 'r') as handle: - self.edam = {} - for idx, line in enumerate(handle.readlines()): - fields = line.split('\t') - if not fields[0].startswith('http://edamontology.org/'): - continue - term_id = fields[0][len('http://edamontology.org/'):] - self.edam[term_id] = fields[1] # preferred label + self._load_edam() if self.app.name == 'galaxy' and self._integrated_tool_panel_config_has_contents: # Load self._tool_panel based on the order in self._integrated_tool_panel. @@ -130,6 +124,53 @@ def __init__(self, config_filenames, tool_root_dir, app, save_integrated_tool_pa if save_integrated_tool_panel: self._save_integrated_tool_panel() + def _recurse_edam_parents(self, term, path=None): + log.debug(f"term:{term} path:{path} parents:{self.edam[term]['parents']}") + if self.edam[term]['parents'] and len(self.edam[term]['parents']) > 0: + for parent in self.edam[term]['parents']: + yield from self._recurse_edam_parents(parent, path + [parent]) + else: + yield path + + def _load_edam(self): + if not self.app.config.enable_beta_edam_toolbox: + return + log.debug('Loading EDAM Terms') + + if not os.path.exists(self.app.config.beta_edam_toolbox_ontology_path): + log.debug('EDAM ontology file not present, downloading') + + page = urllib.request.urlopen(self.app.config.beta_edam_ontology_url) + sniff.stream_to_open_named_file(page, os.open(self.app.config.beta_edam_toolbox_ontology_path, os.O_WRONLY | os.O_CREAT), None, source_encoding=get_charset_from_http_headers(page.headers)) + + log.debug('Processing EDAM Terms') + with open(self.app.config.beta_edam_toolbox_ontology_path, 'r') as handle: + log.debug(f'Processing {handle}') + self.edam = {} + for idx, line in enumerate(handle.readlines()): + fields = line.split('\t') + if not fields[0].startswith('http://edamontology.org/'): + continue + term_id = fields[0][len('http://edamontology.org/'):] + + # Only care about formats and operations + if not (term_id.startswith('operation_') or term_id.startswith('topic_')): + continue + + parents = fields[7].split('|') + self.edam[term_id] = { + 'label': fields[1], # preferred label + 'parents': [x[len('http://edamontology.org/'):] for x in parents if x.startswith('http://edamontology.org/')], + } + log.debug(f'Loaded term {term_id} => {fields[1]}') + + for term in sorted(self.edam.keys()): + tails = [] + for x in self._recurse_edam_parents(term, path=[]): + if x[-2:] not in tails: + tails.append(x[-2:]) + self.edam[term]['path'] = tails + def create_tool(self, config_file, tool_shed_repository=None, guid=None, **kwds): raise NotImplementedError() @@ -414,31 +455,62 @@ def __add_tool_to_tool_panel(self, tool, panel_component, section=False): def _get_edam_sec(self, tool): edam = tool.edam_operations + tool.edam_topics if len(edam) > 0: - # TODO nicer edam names. for term in edam: - yield term, self.edam.get(term, 'Unknown EDAM Term') + yield term, self.edam.get(term, {'label': f'Unknown EDAM Term {term}'})['label'] else: yield 'uncategorized', 'Uncategorized' - def _get_section(self, val): - for sec_id, sec_nm in self._get_edam_sec(val): - if sec_id not in self._tool_panel: - section = ToolSection({'id': sec_id, 'name': sec_nm, 'version': ''}) - self._tool_panel[sec_id] = section - else: - section = self._tool_panel[sec_id] - yield section + def _get_section(self, sec_id, sec_nm): + if sec_id not in self._tool_panel: + section = ToolSection({'id': sec_id, 'name': sec_nm, 'version': ''}) + self._tool_panel[sec_id] = section + else: + section = self._tool_panel[sec_id] + return section + + def _edam_children_of(self, parentTerm): + for term in self.edam.keys(): + if parentTerm in self.edam[term]['parents']: + yield term + def _load_tool_panel_edam(self): execution_timer = ExecutionTimer() + + # Find the children of the top level topics + operations = ['operation_0004'] + list(self._edam_children_of('operation_0004')) + topics = ['topic_0003'] + list(self._edam_children_of('topic_0003')) + + # Sort them (by english label) + # operations = sorted(operations, key=lambda x: self.edam[x]['label']) + # topics = sorted(topics, key=lambda x: self.edam[x]['label']) + + # Convert these to list of dicts, wherein we'll add our tools/etc. + operations = { + x: {} + for x in operations + } + topics = { + x: {} + for x in topics + } + uncategorized = [] + for key, item_type, val in self._integrated_tool_panel.panel_items_iter(): if item_type == panel_item_types.TOOL: tool_id = key.replace('tool_', '', 1) if tool_id in self._tools_by_id: if tool_id in self._tools_by_id: - for section in self._get_section(val): - self.__add_tool_to_tool_panel(val, section, section=True) - self._integrated_section_by_tool[tool_id] = key, val.name + for term, label in self._get_edam_sec(val): + if term == 'uncategorized': + uncategorized.append((tool_id, key, val, val.name)) + else: + for path in self.edam[term]['path']: + # For 2 component paths, it works, for 1 it does too. + if path[0].startswith('operation_'): + operations[path[0]][tool_id] = (term, tool_id, key, val, val.name) + if path[0].startswith('topic_'): + topics[path[0]][tool_id] = (term, tool_id, key, val, val.name) elif item_type == panel_item_types.WORKFLOW: workflow_id = key.replace('workflow_', '', 1) if workflow_id in self._workflows_by_id: @@ -450,10 +522,19 @@ def _load_tool_panel_edam(self): if section_item_type == panel_item_types.TOOL: tool_id = section_key.replace('tool_', '', 1) if tool_id in self._tools_by_id: - for section in self._get_section(section_val): - self.__add_tool_to_tool_panel(section_val, section, section=True) - self._integrated_section_by_tool[tool_id] = key, val.name - + for term, label in self._get_edam_sec(section_val): + if term == 'uncategorized': + uncategorized.append((tool_id, key, val, val.name)) + else: + for path in self.edam[term]['path']: + # For 2 component paths, it works, for 1 it does too. + if path[0].startswith('operation_'): + operations[path[0]][tool_id] = (term, tool_id, key, section_val, val.name) + if path[0].startswith('topic_'): + topics[path[0]][tool_id] = (term, tool_id, key, section_val, val.name) + # for section in self._get_section(section_val): + # self.__add_tool_to_tool_panel(section_val, section, section=True) + # self._integrated_section_by_tool[tool_id] = key, val.name elif section_item_type == panel_item_types.WORKFLOW: workflow_id = section_key.replace('workflow_', '', 1) if workflow_id in self._workflows_by_id: @@ -462,6 +543,43 @@ def _load_tool_panel_edam(self): log.debug(f"Loaded workflow: {workflow_id} {workflow.name}") log.debug("Loading tool panel finished %s", execution_timer) + # print(operations.keys()) + # print([self._sort_edam_key(x) for x in operations.keys()]) + # print(sorted(operations.keys(), lambda x: self._sort_edam_key(x))) + + for term in sorted(operations.keys(), key=lambda x: self._sort_edam_key(x)): + elem = etree.Element('label') + elem.attrib['text'] = self.edam[term]['label'] + elem.attrib['id'] = term + self._tool_panel['label_' + term] = ToolSectionLabel(elem) + + for (term, tool_id, key, val, val_name) in operations[term].values(): + section = self._get_section(term, self.edam[term]['label']) + self.__add_tool_to_tool_panel(val, section, section=True) + self._integrated_section_by_tool[tool_id] = key, val_name + + for term in sorted(topics.keys(), key=lambda x: self._sort_edam_key(x)): + elem = etree.Element('label') + elem.attrib['text'] = self.edam[term]['label'] + elem.attrib['id'] = term + self._tool_panel['label_' + term] = ToolSectionLabel(elem) + + for (term, tool_id, key, val, val_name) in topics[term].values(): + section = self._get_section(term, self.edam[term]['label']) + self.__add_tool_to_tool_panel(val, section, section=True) + self._integrated_section_by_tool[tool_id] = key, val_name + + section = self._get_section('uncategorized', 'Uncategorized') + # for (tool_id, key, val, val_name) in uncategorized: + # self.__add_tool_to_tool_panel(val, section, section=True) + # self._integrated_section_by_tool[tool_id] = key, val_name + + def _sort_edam_key(self, x): + if x in ('operation_0004', 'topic_0003'): + return '!' + x + else: + return self.edam[x]['label'] + def _load_tool_panel(self): execution_timer = ExecutionTimer() for key, item_type, val in self._integrated_tool_panel.panel_items_iter(): diff --git a/lib/galaxy/tools/unzip_collection.xml b/lib/galaxy/tools/unzip_collection.xml index 917204ad2c0a..3ede9257ddc7 100644 --- a/lib/galaxy/tools/unzip_collection.xml +++ b/lib/galaxy/tools/unzip_collection.xml @@ -5,6 +5,9 @@ + + operation_3359 + @@ -14,7 +17,7 @@ + + operation_3436 + @@ -24,7 +27,7 @@ This tool takes two datasets and creates a dataset pair from them. Mapping over **Example** If you have one collection containing only forward reads and one containing only reverse, this tools will "zip" them together into a simple paired collection. - + .. class:: infomark This tool will create new history datasets for your collection but your quota usage will not increase. diff --git a/lib/galaxy/webapps/galaxy/config_schema.yml b/lib/galaxy/webapps/galaxy/config_schema.yml index a778dc4a208a..320c7e84f6c9 100644 --- a/lib/galaxy/webapps/galaxy/config_schema.yml +++ b/lib/galaxy/webapps/galaxy/config_schema.yml @@ -2341,10 +2341,11 @@ mapping: beta_edam_ontology_url: type: str - default: + default: 'https://edamontology.org/EDAM_1.23.tsv' required: false desc: | Sets the url to the EDAM ontology file. + default_workflow_export_format: type: str default: ga diff --git a/tools/data_source/biomart.xml b/tools/data_source/biomart.xml index 80b9d49c3362..b79a01f6048c 100644 --- a/tools/data_source/biomart.xml +++ b/tools/data_source/biomart.xml @@ -9,6 +9,9 @@ --> Ensembl server + + operation_0224 + diff --git a/tools/data_source/biomart_test.xml b/tools/data_source/biomart_test.xml index 5bc3beb3ce54..5334b94fbc2b 100644 --- a/tools/data_source/biomart_test.xml +++ b/tools/data_source/biomart_test.xml @@ -9,6 +9,9 @@ --> Test server + + operation_0224 + diff --git a/tools/data_source/cbi_rice_mart.xml b/tools/data_source/cbi_rice_mart.xml index 2eeeefcdd9b3..99763f5f178b 100644 --- a/tools/data_source/cbi_rice_mart.xml +++ b/tools/data_source/cbi_rice_mart.xml @@ -6,6 +6,9 @@ --> rice mart + + operation_0224 + diff --git a/tools/data_source/ebi_sra.xml b/tools/data_source/ebi_sra.xml index 48efd796f6ed..11dbf6eef9b6 100644 --- a/tools/data_source/ebi_sra.xml +++ b/tools/data_source/ebi_sra.xml @@ -1,6 +1,9 @@ ENA SRA + + operation_0224 + server + + operation_0224 + - + go to EuPathDB server $GALAXY_URL diff --git a/tools/data_source/fly_modencode.xml b/tools/data_source/fly_modencode.xml index d2b4e352fbcd..f5e776ab7755 100644 --- a/tools/data_source/fly_modencode.xml +++ b/tools/data_source/fly_modencode.xml @@ -1,10 +1,13 @@ server + + operation_0224 + - + go to modENCODE fly server $GALAXY_URL diff --git a/tools/data_source/flymine.xml b/tools/data_source/flymine.xml index fa1c7bd3c52f..6928cc1fb048 100644 --- a/tools/data_source/flymine.xml +++ b/tools/data_source/flymine.xml @@ -6,10 +6,13 @@ --> server + + operation_0224 + - + go to Flymine server $GALAXY_URL diff --git a/tools/data_source/flymine_test.xml b/tools/data_source/flymine_test.xml index 71e23c93b6a4..899b73969c76 100644 --- a/tools/data_source/flymine_test.xml +++ b/tools/data_source/flymine_test.xml @@ -6,10 +6,13 @@ --> server + + operation_0224 + - + go to Flymine server $GALAXY_URL diff --git a/tools/data_source/genbank.xml b/tools/data_source/genbank.xml index 559f7be6484f..8ed5a7c2a50c 100644 --- a/tools/data_source/genbank.xml +++ b/tools/data_source/genbank.xml @@ -1,5 +1,8 @@ + + operation_0224 + diff --git a/tools/data_source/gramene_mart.xml b/tools/data_source/gramene_mart.xml index 4f26fb84f1f6..64feef7dbece 100644 --- a/tools/data_source/gramene_mart.xml +++ b/tools/data_source/gramene_mart.xml @@ -9,6 +9,9 @@ --> Central server + + operation_0224 + @@ -26,7 +29,7 @@ python '$__tool_directory__/data_source.py' '$output' $__app__.config.output_siz - + diff --git a/tools/data_source/hapmapmart.xml b/tools/data_source/hapmapmart.xml index 33da0fcbe75a..c43fa5761e03 100644 --- a/tools/data_source/hapmapmart.xml +++ b/tools/data_source/hapmapmart.xml @@ -13,6 +13,9 @@ --> HapMap Biomart + + operation_0224 + diff --git a/tools/data_source/hbvar.xml b/tools/data_source/hbvar.xml index 78e4099c3ca2..74f926e8c130 100644 --- a/tools/data_source/hbvar.xml +++ b/tools/data_source/hbvar.xml @@ -1,6 +1,9 @@ Human Hemoglobin Variants and Thalassemias + + operation_0224 + diff --git a/tools/data_source/import.xml b/tools/data_source/import.xml index 928d28c61cdb..bc6daecca68b 100644 --- a/tools/data_source/import.xml +++ b/tools/data_source/import.xml @@ -1,5 +1,8 @@ (PSU prepared queries) + + operation_0224 + diff --git a/tools/data_source/intermine.xml b/tools/data_source/intermine.xml index bd6f2d2b5d45..6f574b9b598c 100644 --- a/tools/data_source/intermine.xml +++ b/tools/data_source/intermine.xml @@ -6,10 +6,13 @@ --> server + + operation_0224 + - + go to InterMine server $GALAXY_URL diff --git a/tools/data_source/metabolicmine.xml b/tools/data_source/metabolicmine.xml index e5963e57d789..17e2c7a0535b 100644 --- a/tools/data_source/metabolicmine.xml +++ b/tools/data_source/metabolicmine.xml @@ -1,10 +1,13 @@ server + + operation_0224 + - + go to metabolicMine server $GALAXY_URL diff --git a/tools/data_source/microbial_import.xml b/tools/data_source/microbial_import.xml index 0cebca53bcdb..ef71d9510ae1 100644 --- a/tools/data_source/microbial_import.xml +++ b/tools/data_source/microbial_import.xml @@ -1,4 +1,7 @@ + + operation_0224 + server + + operation_0224 + - + go to modENCODE modMine server $GALAXY_URL diff --git a/tools/data_source/mousemine.xml b/tools/data_source/mousemine.xml index c8667227ac4d..508811f9aacb 100644 --- a/tools/data_source/mousemine.xml +++ b/tools/data_source/mousemine.xml @@ -6,10 +6,13 @@ --> server + + operation_0224 + - + go to MouseMine server $GALAXY_URL diff --git a/tools/data_source/ratmine.xml b/tools/data_source/ratmine.xml index 518ea31f6390..69aca47743ca 100644 --- a/tools/data_source/ratmine.xml +++ b/tools/data_source/ratmine.xml @@ -6,10 +6,13 @@ --> server + + operation_0224 + - + go to Ratmine server $GALAXY_URL diff --git a/tools/data_source/sra.xml b/tools/data_source/sra.xml index dd6e7913a064..31b014e01cfd 100644 --- a/tools/data_source/sra.xml +++ b/tools/data_source/sra.xml @@ -1,5 +1,8 @@ server + + operation_0224 + table browser + + operation_0224 + diff --git a/tools/data_source/ucsc_tablebrowser_archaea.xml b/tools/data_source/ucsc_tablebrowser_archaea.xml index 90e0ebf0fd3c..62258145892a 100644 --- a/tools/data_source/ucsc_tablebrowser_archaea.xml +++ b/tools/data_source/ucsc_tablebrowser_archaea.xml @@ -6,6 +6,9 @@ --> table browser + + operation_0224 + diff --git a/tools/data_source/ucsc_tablebrowser_test.xml b/tools/data_source/ucsc_tablebrowser_test.xml index 07b7e7f8700e..e90bc6d14cdd 100644 --- a/tools/data_source/ucsc_tablebrowser_test.xml +++ b/tools/data_source/ucsc_tablebrowser_test.xml @@ -6,6 +6,9 @@ --> table browser + + operation_0224 + diff --git a/tools/data_source/upload.xml b/tools/data_source/upload.xml index 72c3a87d8fb8..1f041f9a1437 100644 --- a/tools/data_source/upload.xml +++ b/tools/data_source/upload.xml @@ -2,6 +2,9 @@ from your computer + + operation_0224 + diff --git a/tools/data_source/worm_modencode.xml b/tools/data_source/worm_modencode.xml index fcbf6b07fb02..1c6f4be9c746 100644 --- a/tools/data_source/worm_modencode.xml +++ b/tools/data_source/worm_modencode.xml @@ -1,10 +1,13 @@ server + + operation_0224 + - + go to modENCODE worm server $GALAXY_URL diff --git a/tools/data_source/wormbase.xml b/tools/data_source/wormbase.xml index c1100a4c794e..d279bdf7f761 100644 --- a/tools/data_source/wormbase.xml +++ b/tools/data_source/wormbase.xml @@ -1,10 +1,13 @@ server + + operation_0224 + - + go to Wormbase server $GALAXY_URL diff --git a/tools/data_source/wormbase_test.xml b/tools/data_source/wormbase_test.xml index 5f70bb3e0723..9e2e96094712 100644 --- a/tools/data_source/wormbase_test.xml +++ b/tools/data_source/wormbase_test.xml @@ -1,10 +1,13 @@ test server + + operation_0224 + - + go to Wormbase test server $GALAXY_URL diff --git a/tools/data_source/yeastmine.xml b/tools/data_source/yeastmine.xml index 75abaa4f78b2..87ff7fdf73e4 100644 --- a/tools/data_source/yeastmine.xml +++ b/tools/data_source/yeastmine.xml @@ -1,10 +1,13 @@ server + + operation_0224 + - + go to yeastMine server $GALAXY_URL diff --git a/tools/data_source/zebrafishmine.xml b/tools/data_source/zebrafishmine.xml index d717274b279e..18c51fce2131 100644 --- a/tools/data_source/zebrafishmine.xml +++ b/tools/data_source/zebrafishmine.xml @@ -1,10 +1,13 @@ server + + operation_0224 + - + go to ZebrafishMine server $GALAXY_URL diff --git a/tools/filters/axt_to_concat_fasta.xml b/tools/filters/axt_to_concat_fasta.xml index 5ded7a2a2727..fb5a15824597 100644 --- a/tools/filters/axt_to_concat_fasta.xml +++ b/tools/filters/axt_to_concat_fasta.xml @@ -32,7 +32,7 @@ This tool converts an AXT formatted file to the FASTA format, and concatenates the results in the same build. -- **AXT format** The alignments are produced from Blastz, an alignment tool available from Webb Miller's lab at Penn State University. The lav format Blastz output, which does not include the sequence, was converted to AXT format with lavToAxt. Each alignment block in an AXT file contains three lines: a summary line and 2 sequence lines. Blocks are separated from one another by blank lines. +- **AXT format** The alignments are produced from Blastz, an alignment tool available from Webb Miller's lab at Penn State University. The lav format Blastz output, which does not include the sequence, was converted to AXT format with lavToAxt. Each alignment block in an AXT file contains three lines: a summary line and 2 sequence lines. Blocks are separated from one another by blank lines. - **FASTA format** a text-based format for representing both nucleic and protein sequences, in which base pairs or proteins are represented using a single-letter code. diff --git a/tools/filters/catWrapper.xml b/tools/filters/catWrapper.xml index 33e67e1e5a45..430c019a1390 100644 --- a/tools/filters/catWrapper.xml +++ b/tools/filters/catWrapper.xml @@ -1,5 +1,8 @@ tail-to-head + + operation_3436 + catWrapper.py $out_file1 diff --git a/tools/filters/commWrapper.xml b/tools/filters/commWrapper.xml index b95b1dd642b3..0b26c4028d3e 100644 --- a/tools/filters/commWrapper.xml +++ b/tools/filters/commWrapper.xml @@ -1,5 +1,8 @@ between two datasets + + operation_3695 + to find common or distinct rows joinWrapper.py $input1 $input2 $field1 $field2 $mode $out_file1 + + operation_3695 + @@ -55,7 +58,7 @@ This tool finds lines in one dataset that HAVE or DO NOT HAVE a common field wit If this is **First dataset**:: - chr1 10 20 geneA + chr1 10 20 geneA chr1 50 80 geneB chr5 10 40 geneL @@ -68,7 +71,7 @@ and this is **Second dataset**:: Finding lines of the **First dataset** whose 4th column matches the 1st column of the **Second dataset** yields:: - chr1 10 20 geneA + chr1 10 20 geneA chr1 50 80 geneB Conversely, using option **Non Matching rows of First dataset** on the same fields will yield:: diff --git a/tools/filters/cutWrapper.xml b/tools/filters/cutWrapper.xml index d62555668471..f47376c3879e 100644 --- a/tools/filters/cutWrapper.xml +++ b/tools/filters/cutWrapper.xml @@ -1,5 +1,8 @@ columns from a table + + operation_3695 + a column from one Query against another Query + + operation_3695 + cut -f '$col' '$input1' | grep -f - $match '$input2' > '$out_file1' @@ -36,7 +39,7 @@ and another that is a typical BED file describing genomic location of some ESTs: Using this tool you will be able to tell how many ESTs in Query1 are also preset in Query2 and will output this:: - chr7 115443239 115443802 AA001842_exon_0_0_chr7_115443240_f 0 + chr7 115443239 115443802 AA001842_exon_0_0_chr7_115443240_f 0 if **Match** option is chosen. diff --git a/tools/filters/fixedValueColumn.xml b/tools/filters/fixedValueColumn.xml index 9d31eb377305..6047a8a392f4 100644 --- a/tools/filters/fixedValueColumn.xml +++ b/tools/filters/fixedValueColumn.xml @@ -1,5 +1,8 @@ to an existing dataset + + operation_3096 + perl '$__tool_directory__/fixedValueColumn.pl' '$input' '$out_file1' '$exp' $iterate @@ -9,7 +12,7 @@ perl '$__tool_directory__/fixedValueColumn.pl' '$input' '$out_file1' '$exp' $ite - + @@ -48,7 +51,7 @@ Typing **+** in the text box will generate:: chr1 10 100 geneA + chr2 200 300 geneB + chr2 400 500 geneC + - + You can also add line numbers by selecting **Iterate: YES**. In this case if you enter **1** in the text box you will get:: diff --git a/tools/filters/grep.xml b/tools/filters/grep.xml index c8a83a0121a3..c904bb4c7699 100644 --- a/tools/filters/grep.xml +++ b/tools/filters/grep.xml @@ -1,5 +1,8 @@ lines that match an expression + + operation_3695 + grep.py -i $input -o $out_file1 -pattern '$pattern' -v $invert @@ -39,7 +42,7 @@ **Syntax** -The select tool searches the data for lines containing or not containing a match to the given pattern. Regular Expression is introduced in this tool. A Regular Expression is a pattern describing a certain amount of text. +The select tool searches the data for lines containing or not containing a match to the given pattern. Regular Expression is introduced in this tool. A Regular Expression is a pattern describing a certain amount of text. - **( ) { } [ ] . * ? + \ ^ $** are all special characters. **\\** can be used to "escape" a special character, allowing that special character to be searched for. - **\\A** matches the beginning of a string(but not an internal line). @@ -55,8 +58,8 @@ The select tool searches the data for lines containing or not containing a match - **{** n or n, or n,m **}** specifies an expected number of repetitions of the preceding pattern. - **{n}** The preceding item is matched exactly n times. - - **{n,}** The preceding item is matched n or more times. - - **{n,m}** The preceding item is matched at least n times but not more than m times. + - **{n,}** The preceding item is matched n or more times. + - **{n,m}** The preceding item is matched at least n times but not more than m times. - **[** ... **]** creates a character class. Within the brackets, single characters can be placed. A dash (-) may be used to indicate a range such as **a-z**. - **.** Matches any single character except a newline. @@ -64,10 +67,10 @@ The select tool searches the data for lines containing or not containing a match - **?** The preceding item is optional and matched at most once. - **+** The preceding item will be matched one or more times. - **^** has two meaning: - - matches the beginning of a line or string. + - matches the beginning of a line or string. - indicates negation in a character class. For example, [^...] matches every character except the ones inside brackets. - **$** matches the end of a line or string. -- **\|** Separates alternate possibilities. +- **\|** Separates alternate possibilities. ----- diff --git a/tools/filters/headWrapper.xml b/tools/filters/headWrapper.xml index c01a2e63ec26..477f1f77684f 100644 --- a/tools/filters/headWrapper.xml +++ b/tools/filters/headWrapper.xml @@ -1,5 +1,8 @@ lines from a dataset + + operation_3695 + perl '$__tool_directory__/headWrapper.pl' '$input' $lineNum '$out_file1' From e506ebf10c0a63dd7d114e63c3ac38f4881a9da8 Mon Sep 17 00:00:00 2001 From: Helena Rasche Date: Fri, 30 Oct 2020 16:44:20 +0100 Subject: [PATCH 6/9] Remove option for url --- doc/source/admin/galaxy_options.rst | 12 +----------- lib/galaxy/config/sample/galaxy.yml.sample | 5 +---- lib/galaxy/tools/toolbox/base.py | 2 +- lib/galaxy/webapps/galaxy/config_schema.yml | 9 +-------- 4 files changed, 4 insertions(+), 24 deletions(-) diff --git a/doc/source/admin/galaxy_options.rst b/doc/source/admin/galaxy_options.rst index 4ef30366b0a8..68cd7a8a41b4 100644 --- a/doc/source/admin/galaxy_options.rst +++ b/doc/source/admin/galaxy_options.rst @@ -3199,17 +3199,7 @@ Sets the path to EDAM ontology file. The value of this option will be resolved with respect to . -:Default: ``EDAM_1.23.tsv`` -:Type: str - - -~~~~~~~~~~~~~~~~~~~~~~~~~~ -``beta_edam_ontology_url`` -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:Description: - Sets the url to the EDAM ontology file. -:Default: ``https://edamontology.org/EDAM_1.23.tsv`` +:Default: ``EDAM.tsv`` :Type: str diff --git a/lib/galaxy/config/sample/galaxy.yml.sample b/lib/galaxy/config/sample/galaxy.yml.sample index 235b7db883e2..6cfb7732fe2d 100644 --- a/lib/galaxy/config/sample/galaxy.yml.sample +++ b/lib/galaxy/config/sample/galaxy.yml.sample @@ -1596,10 +1596,7 @@ galaxy: # Sets the path to EDAM ontology file. # The value of this option will be resolved with respect to # . - #beta_edam_toolbox_ontology_path: EDAM_1.23.tsv - - # Sets the url to the EDAM ontology file. - #beta_edam_ontology_url: https://edamontology.org/EDAM_1.23.tsv + #beta_edam_toolbox_ontology_path: EDAM.tsv # Default format for the export of workflows. Possible values are 'ga' # or 'format2'. diff --git a/lib/galaxy/tools/toolbox/base.py b/lib/galaxy/tools/toolbox/base.py index 902d86f2e80e..328d98f0e553 100644 --- a/lib/galaxy/tools/toolbox/base.py +++ b/lib/galaxy/tools/toolbox/base.py @@ -140,7 +140,7 @@ def _load_edam(self): if not os.path.exists(self.app.config.beta_edam_toolbox_ontology_path): log.debug('EDAM ontology file not present, downloading') - page = urllib.request.urlopen(self.app.config.beta_edam_ontology_url) + page = urllib.request.urlopen('https://edamontology.org/EDAM.tsv') sniff.stream_to_open_named_file(page, os.open(self.app.config.beta_edam_toolbox_ontology_path, os.O_WRONLY | os.O_CREAT), None, source_encoding=get_charset_from_http_headers(page.headers)) log.debug('Processing EDAM Terms') diff --git a/lib/galaxy/webapps/galaxy/config_schema.yml b/lib/galaxy/webapps/galaxy/config_schema.yml index 320c7e84f6c9..9aaf8f29b99c 100644 --- a/lib/galaxy/webapps/galaxy/config_schema.yml +++ b/lib/galaxy/webapps/galaxy/config_schema.yml @@ -2333,19 +2333,12 @@ mapping: beta_edam_toolbox_ontology_path: type: str - default: EDAM_1.23.tsv + default: EDAM.tsv path_resolves_to: data_dir required: false desc: | Sets the path to EDAM ontology file. - beta_edam_ontology_url: - type: str - default: 'https://edamontology.org/EDAM_1.23.tsv' - required: false - desc: | - Sets the url to the EDAM ontology file. - default_workflow_export_format: type: str default: ga From 920549b66b9d858eb43c7c8f82ee8d6823cea407 Mon Sep 17 00:00:00 2001 From: Helena Rasche Date: Fri, 30 Oct 2020 16:48:15 +0100 Subject: [PATCH 7/9] Hide unused labels, remove logging Re-add uncategorized, remove WFs, not sure working --- lib/galaxy/tools/toolbox/base.py | 71 ++++++++++++++----------- test/unit/unittest_utils/galaxy_mock.py | 1 + 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/lib/galaxy/tools/toolbox/base.py b/lib/galaxy/tools/toolbox/base.py index 328d98f0e553..6e4f8b6a26a5 100644 --- a/lib/galaxy/tools/toolbox/base.py +++ b/lib/galaxy/tools/toolbox/base.py @@ -8,8 +8,8 @@ OrderedDict ) from errno import ENOENT -from urllib.parse import urlparse import urllib.request +from urllib.parse import urlparse from markupsafe import escape @@ -473,7 +473,6 @@ def _edam_children_of(self, parentTerm): if parentTerm in self.edam[term]['parents']: yield term - def _load_tool_panel_edam(self): execution_timer = ExecutionTimer() @@ -506,17 +505,21 @@ def _load_tool_panel_edam(self): uncategorized.append((tool_id, key, val, val.name)) else: for path in self.edam[term]['path']: - # For 2 component paths, it works, for 1 it does too. + if len(path) == 1: + t = term + else: + t = path[0] + if path[0].startswith('operation_'): - operations[path[0]][tool_id] = (term, tool_id, key, val, val.name) - if path[0].startswith('topic_'): - topics[path[0]][tool_id] = (term, tool_id, key, val, val.name) - elif item_type == panel_item_types.WORKFLOW: - workflow_id = key.replace('workflow_', '', 1) - if workflow_id in self._workflows_by_id: - workflow = self._workflows_by_id[workflow_id] - self._tool_panel[key] = workflow - log.debug(f"Loaded workflow: {workflow_id} {workflow.name}") + operations[t][tool_id] = (term, tool_id, key, val, val.name) + elif path[0].startswith('topic_'): + topics[t][tool_id] = (term, tool_id, key, val, val.name) + # elif item_type == panel_item_types.WORKFLOW: + # workflow_id = key.replace('workflow_', '', 1) + # if workflow_id in self._workflows_by_id: + # workflow = self._workflows_by_id[workflow_id] + # self._tool_panel[key] = workflow + # log.debug(f"Loaded workflow: {workflow_id} {workflow.name}") elif item_type == panel_item_types.SECTION: for section_key, section_item_type, section_val in val.panel_items_iter(): if section_item_type == panel_item_types.TOOL: @@ -524,30 +527,30 @@ def _load_tool_panel_edam(self): if tool_id in self._tools_by_id: for term, label in self._get_edam_sec(section_val): if term == 'uncategorized': - uncategorized.append((tool_id, key, val, val.name)) + uncategorized.append((tool_id, key, section_val, val.name)) else: for path in self.edam[term]['path']: - # For 2 component paths, it works, for 1 it does too. + if len(path) == 1: + t = term + else: + t = path[0] + if path[0].startswith('operation_'): - operations[path[0]][tool_id] = (term, tool_id, key, section_val, val.name) + operations[t][tool_id] = (term, tool_id, key, section_val, val.name) if path[0].startswith('topic_'): - topics[path[0]][tool_id] = (term, tool_id, key, section_val, val.name) - # for section in self._get_section(section_val): - # self.__add_tool_to_tool_panel(section_val, section, section=True) - # self._integrated_section_by_tool[tool_id] = key, val.name - elif section_item_type == panel_item_types.WORKFLOW: - workflow_id = section_key.replace('workflow_', '', 1) - if workflow_id in self._workflows_by_id: - workflow = self._workflows_by_id[workflow_id] - section.elems[section_key] = workflow - log.debug(f"Loaded workflow: {workflow_id} {workflow.name}") + topics[t][tool_id] = (term, tool_id, key, section_val, val.name) + # elif section_item_type == panel_item_types.WORKFLOW: + # workflow_id = section_key.replace('workflow_', '', 1) + # if workflow_id in self._workflows_by_id: + # workflow = self._workflows_by_id[workflow_id] + # section.elems[section_key] = workflow + # log.debug(f"Loaded workflow: {workflow_id} {workflow.name}") log.debug("Loading tool panel finished %s", execution_timer) - # print(operations.keys()) - # print([self._sort_edam_key(x) for x in operations.keys()]) - # print(sorted(operations.keys(), lambda x: self._sort_edam_key(x))) - for term in sorted(operations.keys(), key=lambda x: self._sort_edam_key(x)): + if len(operations[term].keys()) == 0: + continue + elem = etree.Element('label') elem.attrib['text'] = self.edam[term]['label'] elem.attrib['id'] = term @@ -559,6 +562,9 @@ def _load_tool_panel_edam(self): self._integrated_section_by_tool[tool_id] = key, val_name for term in sorted(topics.keys(), key=lambda x: self._sort_edam_key(x)): + if len(topics[term].keys()) == 0: + continue + elem = etree.Element('label') elem.attrib['text'] = self.edam[term]['label'] elem.attrib['id'] = term @@ -570,9 +576,10 @@ def _load_tool_panel_edam(self): self._integrated_section_by_tool[tool_id] = key, val_name section = self._get_section('uncategorized', 'Uncategorized') - # for (tool_id, key, val, val_name) in uncategorized: - # self.__add_tool_to_tool_panel(val, section, section=True) - # self._integrated_section_by_tool[tool_id] = key, val_name + for (tool_id, key, val, val_name) in uncategorized: + print(tool_id, key, val, val_name) + self.__add_tool_to_tool_panel(val, section, section=True) + self._integrated_section_by_tool[tool_id] = key, val_name def _sort_edam_key(self, x): if x in ('operation_0004', 'topic_0003'): diff --git a/test/unit/unittest_utils/galaxy_mock.py b/test/unit/unittest_utils/galaxy_mock.py index 2fc39759f5f2..1f55af673fbe 100644 --- a/test/unit/unittest_utils/galaxy_mock.py +++ b/test/unit/unittest_utils/galaxy_mock.py @@ -162,6 +162,7 @@ def __init__(self, root=None, **kwargs): self.shed_tool_config_file = "config/shed_tool_conf.xml" self.shed_tool_config_file_set = False + self.enable_beta_edam_toolbox = False self.preserve_python_environment = "always" self.enable_beta_gdpr = False self.legacy_eager_objectstore_initialization = True From 88d6db5e6ec32af6cc461602fd74d594ce9f7fb6 Mon Sep 17 00:00:00 2001 From: Nicola Soranzo Date: Thu, 7 Jan 2021 22:51:06 +0000 Subject: [PATCH 8/9] Fix import order --- lib/galaxy/tools/toolbox/base.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/tools/toolbox/base.py b/lib/galaxy/tools/toolbox/base.py index 9b7129565b44..8d14362f9f74 100644 --- a/lib/galaxy/tools/toolbox/base.py +++ b/lib/galaxy/tools/toolbox/base.py @@ -3,12 +3,12 @@ import os import string import time +import urllib.request from collections import ( namedtuple, OrderedDict ) from errno import ENOENT -import urllib.request from urllib.parse import urlparse from markupsafe import escape @@ -44,7 +44,10 @@ ToolSection, ToolSectionLabel ) -from .parser import ensure_tool_conf_item, get_toolbox_parser +from .parser import ( + ensure_tool_conf_item, + get_toolbox_parser +) from .tags import tool_tag_manager log = logging.getLogger(__name__) From 4044d76e35d9616075872d433b6e26591bb936db Mon Sep 17 00:00:00 2001 From: Helena Rasche Date: Fri, 8 Jan 2021 17:29:58 +0100 Subject: [PATCH 9/9] Expect test data in correct location thanks @ic4f --- test/unit/config/test_config_values.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/unit/config/test_config_values.py b/test/unit/config/test_config_values.py index 252dcdcf217e..07c11ba0e37e 100644 --- a/test/unit/config/test_config_values.py +++ b/test/unit/config/test_config_values.py @@ -99,6 +99,7 @@ def _load_paths(self): self._expected_paths = { 'admin_tool_recommendations_path': self._in_config_dir('tool_recommendations_overwrite.yml'), 'auth_config_file': self._in_config_dir('auth_conf.xml'), + 'beta_edam_toolbox_ontology_path': self._in_data_dir('EDAM.tsv'), 'build_sites_config_file': self._in_sample_dir('build_sites.yml.sample'), 'builds_file_path': self._in_root_dir('tool-data/shared/ucsc/builds.txt'), 'citation_cache_data_dir': self._in_data_dir('citations/data'),