Commit 6c93c406 authored by jdurrant's avatar jdurrant
Browse files

Updating with new file management system.

parent c735bc5d
...@@ -10,5 +10,5 @@ src/Webina/src/new/ ...@@ -10,5 +10,5 @@ src/Webina/src/new/
src/Webina/src/orig/ src/Webina/src/orig/
src/example/small/ src/example/small/
src/example/src/ src/example/src/
dist ./dist
webina.zip webina.zip
Changes Changes
======= =======
1.0.4 WIP
---------
Need to update README.md explaining webina.zip now in releases.
Need to add grant info, and to update citation.
add Grant number and citation to all web apps. Also licenses?
Good to mmention that all errors interpreted as file not found. For exampmle, when ligand was B (from commmand line):
Output will be ligand_final_out.pdbqt
WARNING: at low exhaustiveness, it may be impossible to utilize all CPUs
Reading input ...
Parse error on line 45 in file "ligand_final.pdbqt": ATOM syntax incorrect: "B" is not a valid AutoDock type. Note that AutoDock atom types are case-sensitive.
But in browser:
No such file or directory.
Would be good to be able to catch errors better:
Uncaught 5347440 - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch.
1.0.3 1.0.3
----- -----
......
...@@ -101,13 +101,23 @@ let methodsFunctions = { ...@@ -101,13 +101,23 @@ let methodsFunctions = {
this["gen3D"], this["gen3D"],
parseFloat(this["phVal"]) parseFloat(this["phVal"])
).then((out) => { ).then((out) => {
this.$store.commit("setVar", {
name: this["currentType"] + "Contents",
val: out
});
this["$refs"]["convert-modal"].hide(); this["$refs"]["convert-modal"].hide();
// Update the filename to end in pdbqt.
let newFilename = Utils.replaceExt(
this.$store.state[this["currentType"] + "FileName"],
"converted.pdbqt"
);
// this.$store.commit("updateFileName", { type: this["currentType"], filename: newFilename });
let onConvertDone = this.$store.state["onConvertDone"];
onConvertDone(newFilename, out);
// this.$store.commit("setVar", {
// name: this["currentType"] + "Contents",
// val: out
// });
// This makes it look like it validated. // This makes it look like it validated.
this.$store.commit("setVar", { this.$store.commit("setVar", {
name: this["currentType"] + "ForceValidate", name: this["currentType"] + "ForceValidate",
...@@ -120,10 +130,6 @@ let methodsFunctions = { ...@@ -120,10 +130,6 @@ let methodsFunctions = {
val: true val: true
}); });
// Update the filename to end in pdbqt.
let newFilename = Utils.replaceExt(this.$store.state[this["currentType"] + "FileName"], "converted.pdbqt");
this.$store.commit("updateFileName", { type: this["currentType"], filename: newFilename });
if (successMsgs.length !== 0) { if (successMsgs.length !== 0) {
let overallMsg = successMsgs.map((m, i) => { return "(" + (i + 1).toString() + ") " + m; }).join(" "); let overallMsg = successMsgs.map((m, i) => { return "(" + (i + 1).toString() + ") " + m; }).join(" ");
this["$bvModal"]["msgBoxOk"]("To convert your file to PDBQT, Webina had to make the following modifications: " + overallMsg, { this["$bvModal"]["msgBoxOk"]("To convert your file to PDBQT, Webina had to make the following modifications: " + overallMsg, {
...@@ -138,6 +144,8 @@ let methodsFunctions = { ...@@ -138,6 +144,8 @@ let methodsFunctions = {
return; return;
} }
// All attempts have failed...
this["$refs"]["convert-modal"].hide(); this["$refs"]["convert-modal"].hide();
this["$bvModal"]["msgBoxOk"]("Could not convert your file. Are you sure it is a properly formatted " + this["currentExt"] + " file? If so, it may be too large to convert in the browser.", { this["$bvModal"]["msgBoxOk"]("Could not convert your file. Are you sure it is a properly formatted " + this["currentExt"] + " file? If so, it may be too large to convert in the browser.", {
"title": "Error Converting File!", "title": "Error Converting File!",
...@@ -146,7 +154,7 @@ let methodsFunctions = { ...@@ -146,7 +154,7 @@ let methodsFunctions = {
name: this["currentType"] + "ForceValidate", name: this["currentType"] + "ForceValidate",
val: false val: false
}); });
this.$store.commit("updateFileName", { type: this["currentType"], filename: "" }); // this.$store.commit("updateFileName", { type: this["currentType"], filename: "" });
console.log("ERROR: " + msg); console.log("ERROR: " + msg);
}); });
...@@ -221,17 +229,20 @@ let methodsFunctions = { ...@@ -221,17 +229,20 @@ let methodsFunctions = {
"cancelPressed"(): void { "cancelPressed"(): void {
// Not sure the below is really necessary, but let's just make // Not sure the below is really necessary, but let's just make
// sure. // sure.
this.$store.commit("setVar", { // this.$store.commit("setVar", {
name: this["currentType"] + "FileName", // name: this["currentType"] + "FileName",
val: undefined // val: undefined
}); // });
this.$store.commit("setValidationParam", { this.$store.commit("setValidationParam", {
name: this["currentType"], name: this["currentType"],
val: false val: false
}); });
this.$store.commit("updateFileName", { type: this["currentType"], filename: "" }); // this.$store.commit("updateFileName", { type: this["currentType"], filename: "" });
let onConvertCancel = this.$store.state["onConvertCancel"];
onConvertCancel();
}, },
/** /**
...@@ -262,7 +273,7 @@ export function setup(): void { ...@@ -262,7 +273,7 @@ export function setup(): void {
}, },
"computed": computedFunctions, "computed": computedFunctions,
"methods": methodsFunctions, "methods": methodsFunctions,
"template": ` "template": /* html */ `
<b-modal <b-modal
ref="convert-modal" ref="convert-modal"
@shown="reloadIFrame" @shown="reloadIFrame"
......
...@@ -118,7 +118,7 @@ let methodsFunctions = { ...@@ -118,7 +118,7 @@ let methodsFunctions = {
*/ */
export function setup(): void { export function setup(): void {
Vue.component('vina-existing-output', { Vue.component('vina-existing-output', {
"template": ` "template": /* html */ `
<b-form> <b-form>
<b-card <b-card
class="mb-2 text-center" class="mb-2 text-center"
...@@ -131,27 +131,49 @@ export function setup(): void { ...@@ -131,27 +131,49 @@ export function setup(): void {
</b-card> </b-card>
<sub-section title="Existing Output Files"> <sub-section title="Existing Output Files">
<file-input <!-- TODO: attention here -->
<file-loader-main
label="Receptor" label="Receptor"
id="receptor" id="receptor"
description="The rigid part of the receptor (PDBQT or PDB)." description="The rigid part of the receptor (PDBQT or PDB)."
accept=".pdbqt, .pdb" accept=".pdbqt, .pdb"
></file-input> ></file-loader-main>
<!-- <file-input
label="Receptor"
id="receptor"
description="The rigid part of the receptor (PDBQT or PDB)."
accept=".pdbqt, .pdb"
></file-input> -->
<file-input <!-- TODO: attention here -->
<file-loader-main
label="Docked Output" label="Docked Output"
id="output" id="output"
description="The Webina/Vina output file (PDBQT, OUT, VINA, or TXT) containing docked ligand poses." description="The Webina/Vina output file (PDBQT, OUT, VINA, or TXT) containing docked ligand poses."
accept=".pdbqt, .out, .vina, .txt" accept=".pdbqt, .out, .vina, .txt"
></file-input> ></file-loader-main>
<!-- <file-input
label="Docked Output"
id="output"
description="The Webina/Vina output file (PDBQT, OUT, VINA, or TXT) containing docked ligand poses."
accept=".pdbqt, .out, .vina, .txt"
></file-input> -->
<file-input <!-- TODO: attention here -->
<file-loader-main
label="Correct Pose"
id="crystal"
:required="false"
description="The correct ligand pose, if known from experiment. This PDBQT or PDB file is optional."
accept=".pdbqt, .pdb"
></file-loader-main>
<!-- <file-input
label="Correct Pose" label="Correct Pose"
id="crystal" id="crystal"
:required="false" :required="false"
description="The correct ligand pose, if known from experiment. This PDBQT or PDB file is optional." description="The correct ligand pose, if known from experiment. This PDBQT or PDB file is optional."
accept=".pdbqt, .pdb" accept=".pdbqt, .pdb"
></file-input> ></file-input> -->
</sub-section> </sub-section>
<form-button cls="float-right mb-4" @click.native="onSubmitClick" variant="primary">Load Files</form-button> <form-button cls="float-right mb-4" @click.native="onSubmitClick" variant="primary">Load Files</form-button>
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
import * as Utils from "../../Utils"; import * as Utils from "../../Utils";
import { IConvert, IFileLoaded, IFileLoadError } from "../Forms/FileLoader/Common/Interfaces";
import { getExt } from "../Forms/FileLoader/Common/Utils";
declare var Vue; declare var Vue;
declare var Webina; declare var Webina;
...@@ -238,10 +240,12 @@ let methodsFunctions = { ...@@ -238,10 +240,12 @@ let methodsFunctions = {
if (pass === false) { if (pass === false) {
if (modalWarning === true) { if (modalWarning === true) {
this.$store.commit("openModal", { this.onError(
title: "Invalid Parameters!", "Invalid Parameters!",
body: "<p>Please correct the following parameter(s) before continuing: <code>" + badParams.join(" ") + "</code></p>" "Please correct the following parameter(s) before continuing: <code>"
}); + badParams.join(" ")
+ "</code>"
);
} }
} }
...@@ -253,6 +257,61 @@ let methodsFunctions = { ...@@ -253,6 +257,61 @@ let methodsFunctions = {
return pass; return pass;
}, },
onError(title: string, msg: string): void {
this.$store.commit("openModal", {
title: title,
body: `<p>${msg}</p>`
});
},
"onFileLoaded"(fileInfo: IFileLoaded): void {
this.$store.commit("updateFileName", {
type: this["id"],
filename: fileInfo.filename,
});
// this.getModelFileContents(this["file"]).then((text: string) => {
this.$store.commit("setVar", {
name: fileInfo.id + "Contents",
val: fileInfo.fileContents,
});
// Reset the show non-protein atom's link.
if (fileInfo.id === "receptor") {
this.$store.commit("setVar", {
name: "showKeepProteinOnlyLink",
val: true,
});
}
// });
},
"onConvertNeeded"(convertInfo: IConvert): void {
// Set the filename.
this.$store.commit("updateFileName", {
type: convertInfo.id,
filename: convertInfo.filename,
});
let ext = getExt(convertInfo.filename);
// this.getModelFileContents(val).then((text: string) => {
this.$store.commit("openConvertFileModal", {
ext: ext,
type: convertInfo.id,
file: convertInfo.fileContents,
onConvertCancel: convertInfo.onConvertCancel,
onConvertDone: convertInfo.onConvertDone,
});
// });
alert("");
// Handle below!!!
// convertInfo.onConvertCancel
// convertInfo.onConvertDone
},
/** /**
* Runs after the Vina WASM file is complete. * Runs after the Vina WASM file is complete.
* @param {string} outPdbqtFileTxt The contents of the Vina output pdbqt file. * @param {string} outPdbqtFileTxt The contents of the Vina output pdbqt file.
...@@ -302,10 +361,17 @@ let methodsFunctions = { ...@@ -302,10 +361,17 @@ let methodsFunctions = {
* @returns void * @returns void
*/ */
showWebinaError(message: string): void { showWebinaError(message: string): void {
this.$store.commit("openModal", { this.onError(
title: "Webina Error!", "Webina Error!",
body: "<p>Webina returned the following error: <code>" + message + "</code></p>" "Webina returned the following error: <code>" + message + "</code>"
}); );
},
"showFileLoaderError"(error: IFileLoadError): void {
this.onError(
error.title,
error.body
);
} }
} }
...@@ -323,7 +389,7 @@ function mountedFunction(): void { ...@@ -323,7 +389,7 @@ function mountedFunction(): void {
*/ */
export function setup(): void { export function setup(): void {
Vue.component('vina-params', { Vue.component('vina-params', {
"template": ` "template": /* html */ `
<div> <div>
<b-form v-if="webAssemblyAvaialble"> <b-form v-if="webAssemblyAvaialble">
<b-card <b-card
...@@ -337,12 +403,23 @@ export function setup(): void { ...@@ -337,12 +403,23 @@ export function setup(): void {
</b-card> </b-card>
<sub-section title="Input (PDBQT) Files" v-if="showFileInputs"> <sub-section title="Input (PDBQT) Files" v-if="showFileInputs">
<file-input <!-- TODO: Attention here -->
<file-loader
label="Receptor" label="Receptor"
id="receptor" id="receptor"
description="Formats: PDBQT (best), PDB, ENT, XYZ, PQR, MCIF, MMCIF. If PDB, be sure to add polar hydrogen atoms." description="Formats: PDBQT (best), PDB, ENT, XYZ, PQR, MCIF, MMCIF. If PDB, be sure to add polar hydrogen atoms."
accept=".pdbqt" convert=".pdb, .ent, .xyz, .pqr, .mcif, .mmcif" accept=".pdbqt" convert=".pdb, .ent, .xyz, .pqr, .mcif, .mmcif"
:required="true"
:allowUrlInput="false"
:multipleFiles="false"
:countDownToNextInput="-1"
@onError="showFileLoaderError"
@onFileLoaded="onFileLoaded"
@onConvertNeeded="onConvertNeeded"
> >
<!--
@onFileNameChange="fileNameChanged"
@onTimeUp="timeUp" -->
<template v-slot:extraDescription> <template v-slot:extraDescription>
<span v-if="showKeepProteinOnlyLink"> <span v-if="showKeepProteinOnlyLink">
<a href='' @click="onShowKeepProteinOnlyClick($event);">Automatically remove all non-protein atoms?</a> <a href='' @click="onShowKeepProteinOnlyClick($event);">Automatically remove all non-protein atoms?</a>
...@@ -351,24 +428,46 @@ export function setup(): void { ...@@ -351,24 +428,46 @@ export function setup(): void {
<b>(Removed all non-protein atoms!)</b> <b>(Removed all non-protein atoms!)</b>
</span> </span>
</template> </template>
</file-input> </file-loader>
<file-input <!-- TODO: Attention here -->
label="Ligand" <file-loader
label="Ligand(s)"
id="ligand" id="ligand"
description="Formats: PDBQT (best), CAN, MDL, MOL, MOL2, PDB, SD, SDF, SMI, SMILES, XYZ," description="Formats: PDBQT (best), CAN, MDL, MOL, MOL2, PDB, SD, SDF, SMI, SMILES, XYZ,"
accept=".pdbqt" convert=".can, .mdl, .mol, .mol2, .pdb, .sd, .sdf, .smi, .smiles, .xyz" accept=".pdbqt" convert=".can, .mdl, .mol, .mol2, .pdb, .sd, .sdf, .smi, .smiles, .xyz"
:required="true"
:allowUrlInput="false"
:multipleFiles="true"
:countDownToNextInput="-1"
@onError="showFileLoaderError"
@onFileLoaded="onFileLoaded"
> >
<!--
@onFileNameChange="fileNameChanged"
@onConvertNeeded="convertNeeded"
@onTimeUp="timeUp" -->
<template v-slot:extraDescription>or <a href='' @click="onDrawLigClick($event);">draw your ligand</a>. We recommend preparing ligand files separately with <a target='_blank' href='https://git.durrantlab.pitt.edu/jdurrant/gypsum_dl'>Gypsum-DL</a>.</template> <template v-slot:extraDescription>or <a href='' @click="onDrawLigClick($event);">draw your ligand</a>. We recommend preparing ligand files separately with <a target='_blank' href='https://git.durrantlab.pitt.edu/jdurrant/gypsum_dl'>Gypsum-DL</a>.</template>
</file-input> </file-loader>
<file-input <!-- TODO: Attention here -->
<file-loader
label="Correct Pose" label="Correct Pose"
id="crystal" id="crystal"
:required="false"
description="The correct ligand pose, if known from experiment. This PDBQT or PDB file is optional." description="The correct ligand pose, if known from experiment. This PDBQT or PDB file is optional."
accept=".pdbqt, .pdb" accept=".pdbqt, .pdb"
></file-input> :required="false"
:allowUrlInput="false"
:multipleFiles="false"
:countDownToNextInput="-1"
@onError="showFileLoaderError"
@onFileLoaded="onFileLoaded"
>
<!--
@onFileNameChange="fileNameChanged"
@onConvertNeeded="convertNeeded"
@onTimeUp="timeUp" -->
</file-loader>
<form-button @click.native="useExampleVinaInputFiles" cls="float-right">Use Example Files</form-button> <!-- variant="default" --> <form-button @click.native="useExampleVinaInputFiles" cls="float-right">Use Example Files</form-button> <!-- variant="default" -->
</sub-section> </sub-section>
......
...@@ -17,7 +17,7 @@ export function setup(): void { ...@@ -17,7 +17,7 @@ export function setup(): void {
new Vue({ new Vue({
"el": '#app', "el": '#app',
"store": Store.store, "store": Store.store,
"template": ` "template": /* html */ `
<div class="container-fluid"> <div class="container-fluid">
<open-modal></open-modal> <open-modal></open-modal>
<convert-file-modal></convert-file-modal> <convert-file-modal></convert-file-modal>
......
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
import * as NumericInput from "../UI/Forms/NumericInput"; import * as NumericInput from "../UI/Forms/NumericInput";
import * as CheckBox from "../UI/Forms/CheckBox"; import * as CheckBox from "../UI/Forms/CheckBox";
import * as FileInput from "../UI/Forms/FileInput"; import * as FileInputSetup from "../UI/Forms/FileLoader/Setup";
import * as FileInputMain from "../UI/Forms/FileLoaderMain.Vue";
import * as VinaParams from "../UI/Tabs/VinaParams"; import * as VinaParams from "../UI/Tabs/VinaParams";
import * as VinaRunning from "../UI/Tabs/VinaRunning"; import * as VinaRunning from "../UI/Tabs/VinaRunning";
import * as VinaOutput from "../UI/Tabs/VinaOutput"; import * as VinaOutput from "../UI/Tabs/VinaOutput";
...@@ -46,7 +47,8 @@ export function setup(): void { ...@@ -46,7 +47,8 @@ export function setup(): void {
NumericInput.setup(); NumericInput.setup();
TripleNumeric.setup(); TripleNumeric.setup();
CheckBox.setup(); CheckBox.setup();
FileInput.setup(); FileInputSetup.setupFileLoader();
FileInputMain.setup();
ResultsTable.setup(); ResultsTable.setup();
VinaParams.setup(); VinaParams.setup();
VinaRunning.setup(); VinaRunning.setup();
......
...@@ -42,6 +42,8 @@ interface IFileConvertModal { ...@@ -42,6 +42,8 @@ interface IFileConvertModal {
ext: string; ext: string;
type: string; type: string;
file: string; file: string;
onConvertCancel: Function;
onConvertDone: Function;
} }
interface IInputFileNames { interface IInputFileNames {
...@@ -78,6 +80,8 @@ export const store = new Vuex.Store({ ...@@ -78,6 +80,8 @@ export const store = new Vuex.Store({
"convertFileExt": "PDB", "convertFileExt": "PDB",
"convertFileType": "receptor", "convertFileType": "receptor",
"convertFile": null, "convertFile": null,
"onConvertCancel": undefined,
"onConvertDone": undefined,
"receptorForceValidate": false, "receptorForceValidate": false,
"ligandForceValidate": false, "ligandForceValidate": false,
"drawSmilesModalShow": false, "drawSmilesModalShow": false,
...@@ -225,6 +229,8 @@ export const store = new Vuex.Store({ ...@@ -225,6 +229,8 @@ export const store = new Vuex.Store({
state["convertFileExt"] = payload.ext; state["convertFileExt"] = payload.ext;
state["convertFileType"] = payload.type; state["convertFileType"] = payload.type;
state["convertFile"] = payload.file; state["convertFile"] = payload.file;
state["onConvertCancel"] = payload.onConvertCancel;
state["onConvertDone"] = payload.onConvertDone;
jQuery("body").removeClass("waiting"); jQuery("body").removeClass("waiting");
}, },
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
// details. Copyright 2020 Jacob D. Durrant. // details. Copyright 2020 Jacob D. Durrant.
// There are a few variables and functions from vina.js that I want to easily // There are a few variables and functions from vina.js that I want to easily
// access from here. // access from here.
var VERSION = "1.0.2"; // Replaced by compile script. var VERSION = "1.0.3"; // Replaced by compile script.
console.log("Webina Library " + VERSION); console.log("Webina Library " + VERSION);
console.log(" Compiled from Vina 1.1.2 codebase:"); console.log(" Compiled from Vina 1.1.2 codebase:");
console.log(" http://vina.scripps.edu/"); console.log(" http://vina.scripps.edu/");
......
...@@ -13,20 +13,22 @@ ...@@ -13,20 +13,22 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.arrayIteratorImpl=function(a){var c=0;return function(){return c<a.length?{done:!1,value:a[c++]}:{done:!0}}};$jscomp.arrayIterator=function(a){return{next:$jscomp.arrayIteratorImpl(a)}};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1; var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.arrayIteratorImpl=function(a){var c=0;return function(){return c<a.length?{done:!1,value:a[c++]}:{done:!0}}};$jscomp.arrayIterator=function(a){return{next:$jscomp.arrayIteratorImpl(a)}};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1;$jscomp.ISOLATE_POLYFILLS=!1;$jscomp.FORCE_POLYFILL_PROMISE=!1;$jscomp.FORCE_POLYFILL_PROMISE_WHEN_NO_UNHANDLED_REJECTION=!1;
$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(a,c,b){a!=Array.prototype&&a!=Object.prototype&&(a[c]=b.value)};$jscomp.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global&&null!=global?global:a};$jscomp.global=$jscomp.getGlobal(this);$jscomp.SYMBOL_PREFIX="jscomp_symbol_";$jscomp.initSymbol=function(){$jscomp.initSymbol=function(){};$jscomp.global.Symbol||($jscomp.global.Symbol=$jscomp.Symbol)}; $jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(a,c,b){if(a==Array.prototype||a==Object.prototype)return a;a[c]=b.value;return a};$jscomp.getGlobal=function(a){a=["object"==typeof globalThis&&globalThis,a,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var c=0;c<a.length;++c){var b=a[c];if(b&&b.Math==Math)return b}throw Error("Cannot find global object");};$jscomp.global=$jscomp.getGlobal(this);