Previous changeset 19:2f7702fd0a4c (2024-05-08) Next changeset 21:e7f1b552a695 (2024-10-29) |
Commit message:
planemo upload for repository https://github.com/usegalaxy-au/tools-au commit c3a90eb12ada44d477541baa4dd6182be29cd554-dirty |
modified:
alphafold.xml macro_output.xml macro_test_output.xml scripts/outputs.py |
added:
scripts/alphafold.html |
removed:
alphafold.html |
b |
diff -r 2f7702fd0a4c -r 6ab1a261520a alphafold.html --- a/alphafold.html Wed May 08 06:26:55 2024 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 |
[ |
b'@@ -1,656 +0,0 @@\n-<!DOCTYPE html>\n-<html lang="en" dir="ltr">\n-\n- <head>\n- <meta charset="utf-8">\n- <meta http-equiv="X-UA-Compatible" content="IE=edge">\n- <meta name="viewport" content="width=device-width, initial-scale=1">\n-\n- <title> Alphafold structure prediction </title>\n-\n- <link rel="preconnect" href="https://fonts.googleapis.com">\n- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>\n- <link href="https://fonts.googleapis.com/css2?family=Ubuntu:wght@300;400;500;700&display=swap" rel="stylesheet">\n- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">\n- <script src="https://cdnjs.cloudflare.com/ajax/libs/chroma-js/2.1.0/chroma.min.js" integrity="sha512-yocoLferfPbcwpCMr8v/B0AB4SWpJlouBwgE0D3ZHaiP1nuu5djZclFEIj9znuqghaZ3tdCMRrreLoM8km+jIQ==" crossorigin="anonymous"></script>\n-\n- <style type="text/css">\n- * {\n- margin: 0;\n- padding: 0;\n- }\n- html, body {\n- width: 100%;\n- font-size: 1rem;\n- }\n- body {\n- font-family: \'Ubuntu\', sans-serif;\n- }\n- canvas {\n- background-color: white;\n- }\n- h1, h2, h3, h4, h5, h6 {\n- color: dodgerblue;\n- text-align: center;\n- font-weight: lighter;\n- }\n- h1 {\n- margin: 2rem;\n- font-size: 3rem;\n- }\n- h2 {\n- font-size: 2rem;\n- margin-top: 1rem;\n- margin-bottom: .5rem;\n- }\n- button.btn {\n- color: #ccc;\n- margin: 1rem;\n- padding: .5rem;\n- font-size: 1rem;\n- min-width: 4rem;\n- border: none;\n- border-radius: .5rem;\n- background-color: grey;\n- transition-duration: 0.25s;\n- cursor: pointer;\n- }\n- button.btn.selected {\n- color: #eee;\n- background-color: dodgerblue;\n- }\n- button.btn.green {\n- color: #eee;\n- background-color: #10941f;\n- }\n- button.btn:focus {\n- outline: none;\n- color: inherit;\n- }\n- button.btn:hover {\n- color: white;\n- box-shadow: 0 0 10px dodgerblue;\n- }\n- button.btn.green:hover {\n- color: white;\n- box-shadow: 0 0 10px limegreen;\n- }\n- .main {\n- min-height: 90vh;\n- position: relative;\n- }\n- .flex {\n- display: flex;\n- justify-content: center;\n- align-items: center;\n- padding: 1rem;\n- }\n- .col {\n- flex-direction: column;\n- flex-grow: 0;\n- }\n- .controls {\n- padding-bottom: 10vh;\n- }\n- .box {\n- padding: .5rem 1rem;\n- margin: .5rem auto;\n- width: fit-content;\n- border-radius: 1rem;\n- }\n- .mono {\n- font-family: monospace;\n- color: #555;\n- background-color: #ddd;\n- padding: .25rem;\n- border-radius: .25rem;\n- }\n- .space-1 {\n- line-height: 1.2;\n- }\n- .space-2 {\n- line-height: 1.5;\n- }\n- .relative {\n- position: relative;\n- }\n- .legend {\n- max-width: 350px;\n- }\n- .legend .scale {\n- display: flex;\n- flex-direction: column;\n- align-items: center;\n- }\n- .legend .color {\n- width: 150px;\n- height: 30px;\n- justify-content: space-between;\n- background: linear-gradient(\n- 90deg,\n- rgba(255,55,0,1) 0%,\n- rgba(216,224,6,1) 33%,\n- rgba(34,213,238,1) 66%,\n- rgba(3,30,148,1) 100%\n- );\n- }\n- .legend .ticks {\n- margin-top: -1rem;\n- width: 180px;\n- justify-content: space-between;\n- }\n- #ngl-root-parent {\n- width: 40vw;\n- height: 30vw;\n- margin: auto;\n- position: relative;\n- }\n- #ngl-root {\n- width: '..b' if (reps.length) {\n- state.representations = {};\n- } else {\n- reps = [DEFAULT_REPRESENTATION];\n- }\n-\n- // Load PDB entry\n- return stage.loadFile(uri(state.model)).then( (o) => {\n- state.modelObject = o;\n- reps.forEach( (r) => addModelRepresentation(r) );\n- stage.setSpin(state.spin);\n- o.autoView();\n- setLoading(0);\n- })\n- }\n-\n- // Representations ---------------------------------------------------------\n-\n- const toggleModelRepresentation = (rep) => {\n- rep in state.representations ?\n- removeModelRepresentation(rep)\n- : addModelRepresentation(rep)\n- }\n-\n- const addModelRepresentation = (rep) => {\n- state.representations[rep] =\n- state.modelObject.addRepresentation(rep, {colorScheme: COLORSCHEME});\n- updateButtons();\n- }\n-\n- const removeModelRepresentation = (rep) => {\n- o = state.representations[rep];\n- state.modelObject.removeRepresentation(o);\n- delete state.representations[rep];\n- updateButtons();\n- }\n-\n- const clearModelRepresentations = () => {\n- state.modelObject && state.modelObject.removeAllRepresentations();\n- state.representations = {};\n- }\n-\n- // Actions -----------------------------------------------------------------\n-\n- const toggleDark = () => {\n- state.darkMode = !state.darkMode;\n- stage.setParameters({\n- backgroundColor: state.darkMode ? \'black\' : \'white\',\n- });\n- const btn = document.querySelector(\'#btn-toggle-dark\');\n- btn && btn.classList.toggle(\'selected\');\n- }\n-\n- const setLoading = (state) => {\n- document.getElementById(\'ngl-loading\')\n- .style.display = state ? \'flex\' : \'none\';\n- state.loading = state;\n- }\n-\n- const toggleSpin = () => {\n- stage.toggleSpin();\n- const btn = document.querySelector(\'#btn-toggle-spin\');\n- btn && btn.classList.toggle(\'selected\');\n- state.spin = !state.spin;\n- }\n-\n- const downloadPng = () => {\n- const params = {\n- factor: 3,\n- antialias: true,\n- }\n- stage.makeImage(params).then( (blob) => {\n- const name = MODELS[state.model].replace(\'.pdb\', \'.png\');\n- const url = URL.createObjectURL(blob);\n- makeDownload(url, name);\n- })\n- }\n-\n- const downloadPdb = () => {\n- const url = uri(state.model);\n- const name = `alphafold_${MODELS[state.model]}`;\n- makeDownload(url, name);\n- }\n-\n- const makeDownload = (url, name) => {\n- // Will not work with cross-origin urls (i.e. during development)\n- console.log(`Creating file download for ${name}, href ${url}`);\n- const saveLink = document.createElement(\'a\');\n- saveLink.href = url;\n- saveLink.download = name;\n- document.body.appendChild(saveLink);\n- saveLink.dispatchEvent(\n- new MouseEvent(\'click\', {\n- bubbles: true,\n- cancelable: true,\n- view: window\n- })\n- );\n- document.body.removeChild(saveLink);\n- }\n-\n- const updateButtons = () => {\n- MODELS.forEach( (name, i) => {\n- const id = `#btn-${name.replace(\'.pdb\', \'\')}`;\n- const btn = document.querySelector(id);\n- if (!btn) return\n- i == state.model ?\n- btn.classList.add(\'selected\')\n- : btn.classList.remove(\'selected\');\n- })\n-\n- REPRESENTATIONS.forEach( (name) => {\n- const id = `#btn-${name}`.replace(\'+\', \'-\');\n- const btn = document.querySelector(id);\n- if (!btn) return\n- if (name in state.representations) {\n- btn.classList.add(\'selected\')\n- } else {\n- btn.classList.remove(\'selected\');\n- }\n- });\n-\n- // Show "Nothing to display" if no representations are selected\n- document.querySelector(\'#ngl-nothing\').style.display =\n- Object.keys(state.representations).length ?\n- \'none\'\n- : \'block\';\n- }\n-\n- </script>\n-\n-</html>\n' |
b |
diff -r 2f7702fd0a4c -r 6ab1a261520a alphafold.xml --- a/alphafold.xml Wed May 08 06:26:55 2024 +0000 +++ b/alphafold.xml Sun Jul 28 20:09:55 2024 +0000 |
[ |
b'@@ -1,9 +1,9 @@\n-<tool id="alphafold" name="Alphafold 2" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@" profile="20.01">\n+<tool id="alphafold" name="Alphafold 2" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@" profile="22.05">\n <description> - AI-guided 3D structural prediction of proteins</description>\n <macros>\n- <token name="@TOOL_VERSION@">2.3.1</token>\n+ <token name="@TOOL_VERSION@">2.3.2</token>\n <token name="@TOOL_MINOR_VERSION@">2.3</token>\n- <token name="@VERSION_SUFFIX@">5</token>\n+ <token name="@VERSION_SUFFIX@">0</token>\n <import>macro_output.xml</import>\n <import>macro_test_output.xml</import>\n </macros>\n@@ -17,12 +17,12 @@\n <xref type="bio.tools">alphafold_2</xref>\n </xrefs>\n <requirements>\n- <container type="docker">neoformit/alphafold:v2.3.1_2</container>\n+ <container type="docker">neoformit/alphafold:v2.3.2_0</container>\n </requirements>\n <required_files>\n <include path="scripts/outputs.py" />\n <include path="scripts/validate_fasta.py" />\n- <include path="alphafold.html" />\n+ <include path="scripts/alphafold.html" />\n </required_files>\n <command detect_errors="exit_code"><![CDATA[\n \n@@ -46,7 +46,7 @@\n && python3 \'$__tool_directory__/scripts/validate_fasta.py\' input.fasta\n --min_length \\${ALPHAFOLD_AA_LENGTH_MIN:-0}\n --max_length \\${ALPHAFOLD_AA_LENGTH_MAX:-0}\n-#if $model_preset == \'multimer\':\n+#if $model_preset.selection == \'multimer\':\n --multimer\n --max-sequences \\${ALPHAFOLD_MAX_SEQUENCES:-10}\n #end if\n@@ -60,7 +60,7 @@\n ## Run AlphaFold -------------------------------------------------------------\n #if os.environ.get(\'PLANEMO_TESTING\'):\n ## Run in testing mode (mocks a successful AlphaFold run by copying outputs)\n- && echo "Creating dummy outputs for model_preset=$model_preset..."\n+ && echo "Creating dummy outputs for model_preset=$model_preset.selection..."\n && bash \'$__tool_directory__/scripts/mock_alphafold.sh\' $model_preset\n #else:\n ## Run AlphaFold\n@@ -68,7 +68,7 @@\n --fasta_paths alphafold.fasta\n --output_dir output\n --data_dir \\${ALPHAFOLD_DB:-/data}/@TOOL_MINOR_VERSION@/\n- --model_preset=$model_preset\n+ --model_preset=$model_preset.selection\n \n ## Set reference database paths\n --uniref90_database_path \\${ALPHAFOLD_DB:-/data}/@TOOL_MINOR_VERSION@/uniref90/uniref90.fasta\n@@ -83,21 +83,33 @@\n --small_bfd_database_path \\${ALPHAFOLD_DB:-/data}/@TOOL_MINOR_VERSION@/small_bfd/bfd-first_non_consensus_sequences.fasta\n #end if\n \n- #if $max_template_date:\n- --max_template_date=$max_template_date\n+ #if $advanced.max_template_date:\n+ --max_template_date=$advanced.max_template_date\n #else\n --max_template_date=\\$TODAY\n #end if\n \n- --use_gpu_relax=\\${ALPHAFOLD_USE_GPU:-True} ## introduced in v2.1.2\n+ --use_gpu_relax=\\${ALPHAFOLD_USE_GPU:-True}\n \n- #if $model_preset == \'multimer\':\n+ #if $model_preset.selection == \'multimer\':\n --pdb_seqres_database_path=\\${ALPHAFOLD_DB:-/data}/@TOOL_MINOR_VERSION@/pdb_seqres/pdb_seqres.txt\n --uniprot_database_path=\\${ALPHAFOLD_DB:-/data}/@TOOL_MINOR_VERSION@/uniprot/uniprot.fasta\n- --num_multimer_predictions_per_model=1 ## introduced in v2.2.0\n+ --num_multimer_predictions_per_model=$model_preset.num_multimer_predictions_per_model\n #else\n --pdb70_database_path \\${ALPHAFOLD_DB:-/data}/@TOOL_MINOR_VERSION@/pdb70/pdb70\n #end if\n+\n+ ## Galaxy-specific options --------------------------------------------\n+ ## See https://github.com/neoformit/alphafold/tree/release_2.3.2_galaxy\n+ #if $advanced.disable_amber_relax:\n+ --disable_amber_relax\n+ #end if\n+\n+ #if $advanced.limit_model_outputs:\n+ --output_models=$limit_model_outputs\n+ #end if\n+ ## End Galaxy-specific options ---------------'..b'ram name="model_preset|selection" value="monomer_ptm"/>\n <param name="outputs|plots" value="true"/>\n <param name="outputs|confidence_scores" value="true"/>\n <param name="outputs|plddts" value="true"/>\n@@ -303,19 +359,21 @@\n <param name="input_mode" value="history"/>\n <param name="fasta_file" value="multimer.fasta"/>\n </conditional>\n- <param name="model_preset" value="multimer"/>\n+ <param name="model_preset|selection" value="multimer"/>\n <param name="outputs|plots" value="true"/>\n <param name="outputs|confidence_scores" value="true"/>\n <param name="outputs|plddts" value="true"/>\n <param name="outputs|pae_csv" value="true"/>\n <param name="outputs|model_pkls" value="true"/>\n <param name="outputs|relax_json" value="true"/>\n+ <param name="outputs|timings_json" value="true"/>\n <expand macro="test_output_plots_3" />\n <expand macro="test_output_confidence_scores" />\n <expand macro="test_output_plddts" />\n <expand macro="test_output_pdb_models" />\n <expand macro="test_output_pickles" />\n <expand macro="test_output_relax_json" />\n+ <expand macro="test_output_timings_json" />\n <expand macro="test_output_pae_csv" />\n </test>\n </tests>\n@@ -325,7 +383,7 @@\n \n | AlphaFold v2: AI-guided 3D structural prediction of proteins\n |\n- | **NOTE: this tool packages AlphaFold v2.3.1.**\n+ | **NOTE: this tool packages** `a modified branch of AlphaFold v2.3.2. <https://github.com/neoformit/alphafold/tree/release_2.3.2_galaxy>`_\n |\n | This means that the neural network has been trained on PDBs with a release\n | date before 2021-09-30 (the training cutoff was 2018-04-30 until ``v2.3.0``).\n@@ -333,12 +391,9 @@\n | Find out more in the technical and release notes:\n |\n \n- - `Release notes for v2.3.1 <https://github.com/deepmind/alphafold/releases/tag/v2.3.1>`_\n+ - `Release notes for v2.3.2 <https://github.com/deepmind/alphafold/releases/tag/v2.3.2>`_\n - `Technical notes for v2.3 <https://github.com/deepmind/alphafold/blob/main/docs/technical_note_v2.3.0.md>`_\n \n- | If you want to use AlphaFold trained against an older cutoff date, switch to Galaxy version ``2.1.2`` (which was trained to data up to 2018-04-30).\n- |\n-\n **What it does**\n \n *What is AlphaFold?*\n@@ -362,6 +417,7 @@\n | You can choose to input either a file from your Galaxy history or paste a sequence into a text box.\n | If you choose the ``multimer`` option, you can supply a FASTA file containing **multiple sequences** to be folded concurrently into a multimer.\n |\n+ | For pairwise screening of target-candidate with multimer, you can submit a list of paired protein sequences in batch mode (i.e. two protein sequences in each FASTA file).\n |\n \n **Outputs**\n@@ -380,7 +436,7 @@\n \n *PDB files*\n \n- | Five PDB (Protein Data Bank) files are be created, ordered by rank, as predicted by AlphaFold.\n+ | PDB (Protein Data Bank) files (5 by default) are be created, ordered by rank, as predicted by AlphaFold. The tool produces 5 models by default, but this can be reduced with the "Limit model outputs" for a reduced run time.\n | These files describe the molecular structures and can be used for downstream analysis. e.g. *in silico* molecular docking.\n | **PLEASE NOTE** that all outputs have been renamed to their respective rank order, including model and model.pkl files.\n |\n@@ -421,6 +477,12 @@\n |\n |\n \n+ *timings.json (optional)*\n+\n+ | A JSON-formatted text file containing the timings for each phase of the prediction.\n+ |\n+ |\n+\n **AlphaFold configuration**\n \n | We have configured AlphaFold to run with the parameters suggested by default on `AlphaFold\'s GitHub <https://github.com/deepmind/alphafold>`_.\n' |
b |
diff -r 2f7702fd0a4c -r 6ab1a261520a macro_output.xml --- a/macro_output.xml Wed May 08 06:26:55 2024 +0000 +++ b/macro_output.xml Sun Jul 28 20:09:55 2024 +0000 |
[ |
@@ -1,9 +1,17 @@ <macros> <xml name="output_pdb_models"> - <data name="model5" format="pdb" from_work_dir="output/alphafold/ranked_4.pdb" label="${tool.name} on ${on_string}: PDB ranked 4"/> - <data name="model4" format="pdb" from_work_dir="output/alphafold/ranked_3.pdb" label="${tool.name} on ${on_string}: PDB ranked 3"/> - <data name="model3" format="pdb" from_work_dir="output/alphafold/ranked_2.pdb" label="${tool.name} on ${on_string}: PDB ranked 2"/> - <data name="model2" format="pdb" from_work_dir="output/alphafold/ranked_1.pdb" label="${tool.name} on ${on_string}: PDB ranked 1"/> + <data name="model5" format="pdb" from_work_dir="output/alphafold/ranked_4.pdb" label="${tool.name} on ${on_string}: PDB ranked 4"> + <filter>advanced['limit_model_outputs'] > 4</filter> + </data> + <data name="model4" format="pdb" from_work_dir="output/alphafold/ranked_3.pdb" label="${tool.name} on ${on_string}: PDB ranked 3"> + <filter>advanced['limit_model_outputs'] > 3</filter> + </data> + <data name="model3" format="pdb" from_work_dir="output/alphafold/ranked_2.pdb" label="${tool.name} on ${on_string}: PDB ranked 2"> + <filter>advanced['limit_model_outputs'] > 2</filter> + </data> + <data name="model2" format="pdb" from_work_dir="output/alphafold/ranked_1.pdb" label="${tool.name} on ${on_string}: PDB ranked 1"> + <filter>advanced['limit_model_outputs'] > 1</filter> + </data> <data name="model1" format="pdb" from_work_dir="output/alphafold/ranked_0.pdb" label="${tool.name} on ${on_string}: PDB ranked 0"/> </xml> @@ -16,6 +24,7 @@ > <filter>outputs['pae_csv']</filter> <filter>model_preset != "monomer"</filter> + <filter>advanced['limit_model_outputs'] > 4</filter> </data> <data name="pae_ranked_3" @@ -25,6 +34,7 @@ > <filter>outputs['pae_csv']</filter> <filter>model_preset != "monomer"</filter> + <filter>advanced['limit_model_outputs'] > 3</filter> </data> <data name="pae_ranked_2" @@ -34,6 +44,7 @@ > <filter>outputs['pae_csv']</filter> <filter>model_preset != "monomer"</filter> + <filter>advanced['limit_model_outputs'] > 2</filter> </data> <data name="pae_ranked_1" @@ -43,6 +54,7 @@ > <filter>outputs['pae_csv']</filter> <filter>model_preset != "monomer"</filter> + <filter>advanced['limit_model_outputs'] > 1</filter> </data> <data name="pae_ranked_0" @@ -63,6 +75,7 @@ label="${tool.name} on ${on_string}: ranked_4.pkl" > <filter>outputs['model_pkls']</filter> + <filter>advanced['limit_model_outputs'] > 4</filter> </data> <data name="output_ranked_3_pkl" @@ -71,6 +84,7 @@ label="${tool.name} on ${on_string}: ranked_3.pkl" > <filter>outputs['model_pkls']</filter> + <filter>advanced['limit_model_outputs'] > 3</filter> </data> <data name="output_ranked_2_pkl" @@ -79,6 +93,7 @@ label="${tool.name} on ${on_string}: ranked_2.pkl" > <filter>outputs['model_pkls']</filter> + <filter>advanced['limit_model_outputs'] > 2</filter> </data> <data name="output_ranked_1_pkl" @@ -87,6 +102,7 @@ label="${tool.name} on ${on_string}: ranked_1.pkl" > <filter>outputs['model_pkls']</filter> + <filter>advanced['limit_model_outputs'] > 1</filter> </data> <data name="output_ranked_0_pkl" @@ -106,6 +122,7 @@ label="${tool.name} on ${on_string}: pLDDT/PAE plot ranked 4" > <filter>outputs['plots']</filter> + <filter>advanced['limit_model_outputs'] > 4</filter> </data> <data name="plot_ranked_3" @@ -114,6 +131,7 @@ label="${tool.name} on ${on_string}: pLDDT/PAE plot ranked 3" > <filter>outputs['plots']</filter> + <filter>advanced['limit_model_outputs'] > 3</filter> </data> <data name="plot_ranked_2" @@ -122,6 +140,7 @@ label="${tool.name} on ${on_string}: pLDDT/PAE plot ranked 2" > <filter>outputs['plots']</filter> + <filter>advanced['limit_model_outputs'] > 2</filter> </data> <data name="plot_ranked_1" @@ -130,6 +149,7 @@ label="${tool.name} on ${on_string}: pLDDT/PAE plot ranked 1" > <filter>outputs['plots']</filter> + <filter>advanced['limit_model_outputs'] > 1</filter> </data> <data name="plot_ranked_0" @@ -173,4 +193,15 @@ <filter>outputs['relax_json']</filter> </data> </xml> + + <xml name="output_timings_json"> + <data + name="output_timings_json" + format="json" + from_work_dir="output/alphafold/timings.json" + label="${tool.name} on ${on_string}: timings.json" + > + <filter>outputs['timings_json']</filter> + </data> + </xml> </macros> |
b |
diff -r 2f7702fd0a4c -r 6ab1a261520a macro_test_output.xml --- a/macro_test_output.xml Wed May 08 06:26:55 2024 +0000 +++ b/macro_test_output.xml Sun Jul 28 20:09:55 2024 +0000 |
b |
@@ -26,6 +26,14 @@ </output> </xml> + <xml name="test_output_timings_json"> + <output name="output_timings_json"> + <assert_contents> + <has_size min="500" /> + </assert_contents> + </output> + </xml> + <xml name="test_output_pdb_models"> <output name="model1"> <assert_contents> |
b |
diff -r 2f7702fd0a4c -r 6ab1a261520a scripts/alphafold.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/alphafold.html Sun Jul 28 20:09:55 2024 +0000 |
[ |
b'@@ -0,0 +1,656 @@\n+<!DOCTYPE html>\n+<html lang="en" dir="ltr">\n+\n+ <head>\n+ <meta charset="utf-8">\n+ <meta http-equiv="X-UA-Compatible" content="IE=edge">\n+ <meta name="viewport" content="width=device-width, initial-scale=1">\n+\n+ <title> Alphafold structure prediction </title>\n+\n+ <link rel="preconnect" href="https://fonts.googleapis.com">\n+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>\n+ <link href="https://fonts.googleapis.com/css2?family=Ubuntu:wght@300;400;500;700&display=swap" rel="stylesheet">\n+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">\n+ <script src="https://cdnjs.cloudflare.com/ajax/libs/chroma-js/2.1.0/chroma.min.js" integrity="sha512-yocoLferfPbcwpCMr8v/B0AB4SWpJlouBwgE0D3ZHaiP1nuu5djZclFEIj9znuqghaZ3tdCMRrreLoM8km+jIQ==" crossorigin="anonymous"></script>\n+\n+ <style type="text/css">\n+ * {\n+ margin: 0;\n+ padding: 0;\n+ }\n+ html, body {\n+ width: 100%;\n+ font-size: 1rem;\n+ }\n+ body {\n+ font-family: \'Ubuntu\', sans-serif;\n+ }\n+ canvas {\n+ background-color: white;\n+ }\n+ h1, h2, h3, h4, h5, h6 {\n+ color: dodgerblue;\n+ text-align: center;\n+ font-weight: lighter;\n+ }\n+ h1 {\n+ margin: 2rem;\n+ font-size: 3rem;\n+ }\n+ h2 {\n+ font-size: 2rem;\n+ margin-top: 1rem;\n+ margin-bottom: .5rem;\n+ }\n+ button.btn {\n+ color: #ccc;\n+ margin: 1rem;\n+ padding: .5rem;\n+ font-size: 1rem;\n+ min-width: 4rem;\n+ border: none;\n+ border-radius: .5rem;\n+ background-color: grey;\n+ transition-duration: 0.25s;\n+ cursor: pointer;\n+ }\n+ button.btn.selected {\n+ color: #eee;\n+ background-color: dodgerblue;\n+ }\n+ button.btn.green {\n+ color: #eee;\n+ background-color: #10941f;\n+ }\n+ button.btn:focus {\n+ outline: none;\n+ color: inherit;\n+ }\n+ button.btn:hover {\n+ color: white;\n+ box-shadow: 0 0 10px dodgerblue;\n+ }\n+ button.btn.green:hover {\n+ color: white;\n+ box-shadow: 0 0 10px limegreen;\n+ }\n+ .main {\n+ min-height: 90vh;\n+ position: relative;\n+ }\n+ .flex {\n+ display: flex;\n+ justify-content: center;\n+ align-items: center;\n+ padding: 1rem;\n+ }\n+ .col {\n+ flex-direction: column;\n+ flex-grow: 0;\n+ }\n+ .controls {\n+ padding-bottom: 10vh;\n+ }\n+ .box {\n+ padding: .5rem 1rem;\n+ margin: .5rem auto;\n+ width: fit-content;\n+ border-radius: 1rem;\n+ }\n+ .mono {\n+ font-family: monospace;\n+ color: #555;\n+ background-color: #ddd;\n+ padding: .25rem;\n+ border-radius: .25rem;\n+ }\n+ .space-1 {\n+ line-height: 1.2;\n+ }\n+ .space-2 {\n+ line-height: 1.5;\n+ }\n+ .relative {\n+ position: relative;\n+ }\n+ .legend {\n+ max-width: 350px;\n+ }\n+ .legend .scale {\n+ display: flex;\n+ flex-direction: column;\n+ align-items: center;\n+ }\n+ .legend .color {\n+ width: 150px;\n+ height: 30px;\n+ justify-content: space-between;\n+ background: linear-gradient(\n+ 90deg,\n+ rgba(255,55,0,1) 0%,\n+ rgba(216,224,6,1) 33%,\n+ rgba(34,213,238,1) 66%,\n+ rgba(3,30,148,1) 100%\n+ );\n+ }\n+ .legend .ticks {\n+ margin-top: -1rem;\n+ width: 180px;\n+ justify-content: space-between;\n+ }\n+ #ngl-root-parent {\n+ width: 40vw;\n+ height: 30vw;\n+ margin: auto;\n+ position: relative;\n+ }\n+ #ngl-root {\n+ width: '..b' if (reps.length) {\n+ state.representations = {};\n+ } else {\n+ reps = [DEFAULT_REPRESENTATION];\n+ }\n+\n+ // Load PDB entry\n+ return stage.loadFile(uri(state.model)).then( (o) => {\n+ state.modelObject = o;\n+ reps.forEach( (r) => addModelRepresentation(r) );\n+ stage.setSpin(state.spin);\n+ o.autoView();\n+ setLoading(0);\n+ })\n+ }\n+\n+ // Representations ---------------------------------------------------------\n+\n+ const toggleModelRepresentation = (rep) => {\n+ rep in state.representations ?\n+ removeModelRepresentation(rep)\n+ : addModelRepresentation(rep)\n+ }\n+\n+ const addModelRepresentation = (rep) => {\n+ state.representations[rep] =\n+ state.modelObject.addRepresentation(rep, {colorScheme: COLORSCHEME});\n+ updateButtons();\n+ }\n+\n+ const removeModelRepresentation = (rep) => {\n+ o = state.representations[rep];\n+ state.modelObject.removeRepresentation(o);\n+ delete state.representations[rep];\n+ updateButtons();\n+ }\n+\n+ const clearModelRepresentations = () => {\n+ state.modelObject && state.modelObject.removeAllRepresentations();\n+ state.representations = {};\n+ }\n+\n+ // Actions -----------------------------------------------------------------\n+\n+ const toggleDark = () => {\n+ state.darkMode = !state.darkMode;\n+ stage.setParameters({\n+ backgroundColor: state.darkMode ? \'black\' : \'white\',\n+ });\n+ const btn = document.querySelector(\'#btn-toggle-dark\');\n+ btn && btn.classList.toggle(\'selected\');\n+ }\n+\n+ const setLoading = (state) => {\n+ document.getElementById(\'ngl-loading\')\n+ .style.display = state ? \'flex\' : \'none\';\n+ state.loading = state;\n+ }\n+\n+ const toggleSpin = () => {\n+ stage.toggleSpin();\n+ const btn = document.querySelector(\'#btn-toggle-spin\');\n+ btn && btn.classList.toggle(\'selected\');\n+ state.spin = !state.spin;\n+ }\n+\n+ const downloadPng = () => {\n+ const params = {\n+ factor: 3,\n+ antialias: true,\n+ }\n+ stage.makeImage(params).then( (blob) => {\n+ const name = MODELS[state.model].replace(\'.pdb\', \'.png\');\n+ const url = URL.createObjectURL(blob);\n+ makeDownload(url, name);\n+ })\n+ }\n+\n+ const downloadPdb = () => {\n+ const url = uri(state.model);\n+ const name = `alphafold_${MODELS[state.model]}`;\n+ makeDownload(url, name);\n+ }\n+\n+ const makeDownload = (url, name) => {\n+ // Will not work with cross-origin urls (i.e. during development)\n+ console.log(`Creating file download for ${name}, href ${url}`);\n+ const saveLink = document.createElement(\'a\');\n+ saveLink.href = url;\n+ saveLink.download = name;\n+ document.body.appendChild(saveLink);\n+ saveLink.dispatchEvent(\n+ new MouseEvent(\'click\', {\n+ bubbles: true,\n+ cancelable: true,\n+ view: window\n+ })\n+ );\n+ document.body.removeChild(saveLink);\n+ }\n+\n+ const updateButtons = () => {\n+ MODELS.forEach( (name, i) => {\n+ const id = `#btn-${name.replace(\'.pdb\', \'\')}`;\n+ const btn = document.querySelector(id);\n+ if (!btn) return\n+ i == state.model ?\n+ btn.classList.add(\'selected\')\n+ : btn.classList.remove(\'selected\');\n+ })\n+\n+ REPRESENTATIONS.forEach( (name) => {\n+ const id = `#btn-${name}`.replace(\'+\', \'-\');\n+ const btn = document.querySelector(id);\n+ if (!btn) return\n+ if (name in state.representations) {\n+ btn.classList.add(\'selected\')\n+ } else {\n+ btn.classList.remove(\'selected\');\n+ }\n+ });\n+\n+ // Show "Nothing to display" if no representations are selected\n+ document.querySelector(\'#ngl-nothing\').style.display =\n+ Object.keys(state.representations).length ?\n+ \'none\'\n+ : \'block\';\n+ }\n+\n+ </script>\n+\n+</html>\n' |
b |
diff -r 2f7702fd0a4c -r 6ab1a261520a scripts/outputs.py --- a/scripts/outputs.py Wed May 08 06:26:55 2024 +0000 +++ b/scripts/outputs.py Sun Jul 28 20:09:55 2024 +0000 |
[ |
@@ -42,6 +42,12 @@ 'multimer': 'iptm+ptm', } +HTML_PATH = Path(__file__).parent / "alphafold.html" +HTML_OUTPUT_FILENAME = 'alphafold.html' +HTML_BUTTON_ATTR = 'class="btn" id="btn-ranked_{rank}"' +HTML_BUTTON_ATTR_DISABLED = ( + 'class="btn disabled" id="btn-ranked_{rank}" disabled') + class Settings: """Parse and store settings/config.""" @@ -188,7 +194,7 @@ """Write per-model confidence scores.""" path = context.settings.workdir / OUTPUTS['model_confidence_scores'] with open(path, 'w') as f: - for rank in range(1, 6): + for rank in range(1, len(context.model_pkl_paths) + 1): score = ranking.get_plddt_for_rank(rank) f.write(f'ranked_{rank - 1}\t{score:.2f}\n') @@ -300,6 +306,22 @@ plt.savefig(png_path) +def template_html(context: ExecutionContext): + """Template HTML file. + + Remove buttons that are redundant with limited model outputs. + """ + print("Templating HTML file...") + with open(HTML_PATH) as f: + html = f.read() + for i in range(len(context.model_pkl_paths), 5): + btn_id = HTML_BUTTON_ATTR.format(rank=i) + btn_attr_disabled = HTML_BUTTON_ATTR_DISABLED.format(rank=i) + html = html.replace(btn_id, btn_attr_disabled) + with open(context.settings.output_dir / HTML_OUTPUT_FILENAME, 'w') as f: + f.write(html) + + def main(): """Parse output files and generate additional output files.""" settings = Settings() @@ -307,6 +329,7 @@ ranking = ResultRanking(context) write_confidence_scores(ranking, context) rekey_relax_metrics(ranking, context) + template_html(context) # Optional outputs if settings.output_model_pkls: |