From a92b0151285bd7eff45934e83cecad9b8ee50939 Mon Sep 17 00:00:00 2001 From: Dialpuri Date: Fri, 27 Oct 2023 14:28:24 +0100 Subject: [PATCH] Major Refactor Changed folder structure Changed mainline components to use props and spreader Extrapolated common functions --- .../components/GlycanDetail/GlycanDetail.jsx | 54 ++---- .../Loading}/Loading.jsx | 0 .../Loading}/PageLoad.jsx | 0 webserver/src/components/Old/BarChart.jsx | 169 ----------------- webserver/src/components/Old/Main.jsx | 15 -- webserver/src/components/Old/NavBar.jsx | 36 ---- webserver/src/components/Old/SVGCarousel.jsx | 63 ------- .../PDBFetch}/PDBFetch.jsx | 0 .../src/components/PrivateerDisplay/SNFG.jsx | 59 +++--- .../{common => components/Submit}/Submit.jsx | 2 +- .../{common => components/Upload}/Upload.jsx | 33 ++-- .../Upload}/UploadButton.jsx | 2 +- webserver/src/layouts/Header.jsx | 44 ++--- webserver/src/pages/Home/HomeSection.jsx | 177 ++++++------------ webserver/src/pages/Main/Main.jsx | 67 ------- webserver/src/utils/fetch_from_pdb.js | 42 +++++ 16 files changed, 178 insertions(+), 585 deletions(-) rename webserver/src/{common => components/Loading}/Loading.jsx (100%) rename webserver/src/{common => components/Loading}/PageLoad.jsx (100%) delete mode 100644 webserver/src/components/Old/BarChart.jsx delete mode 100644 webserver/src/components/Old/Main.jsx delete mode 100644 webserver/src/components/Old/NavBar.jsx delete mode 100644 webserver/src/components/Old/SVGCarousel.jsx rename webserver/src/{common => components/PDBFetch}/PDBFetch.jsx (100%) rename webserver/src/{common => components/Submit}/Submit.jsx (97%) rename webserver/src/{common => components/Upload}/Upload.jsx (60%) rename webserver/src/{common => components/Upload}/UploadButton.jsx (98%) delete mode 100644 webserver/src/pages/Main/Main.jsx create mode 100644 webserver/src/utils/fetch_from_pdb.js diff --git a/webserver/src/components/GlycanDetail/GlycanDetail.jsx b/webserver/src/components/GlycanDetail/GlycanDetail.jsx index 9733b72d..010ca1e1 100644 --- a/webserver/src/components/GlycanDetail/GlycanDetail.jsx +++ b/webserver/src/components/GlycanDetail/GlycanDetail.jsx @@ -1,18 +1,15 @@ import {lazy, useCallback, useEffect, useState} from "react"; import {MoorhenContainer, MoorhenContextProvider} from 'moorhen' import GlycanDetailInfoBox from "./GlycanDetailInfoBox"; -// import GlycanDetailTable from "./GlycanDetailTable"; -// import TorsionPlot from "../TorsionPlot/TorsionPlot"; import TorsionMultiPlot from "../TorsionPlot/TorsionMultiPlot"; -const GlycanDetailTable = lazy(() => import('./GlycanDetailTable')); -export default function GlycanDetail({tableData, hideMoorhen, setHideMoorhen, rowID, forwardControls, scrollPosition, controls, molecule, map}) { +export default function GlycanDetail(props) { async function handle_click(e) { let new_center_string = e.target.dataset.chainid + "/" + e.target.dataset.seqnum + "(" + e.target.dataset.resname + ")" - const selectedMolecule = controls.current.molecules.find((molecule) => molecule.name === "mol-1") + const selectedMolecule = props.controls.current.molecules.find((molecule) => molecule.name === "mol-1") await selectedMolecule.centreOn(new_center_string) } @@ -27,52 +24,32 @@ export default function GlycanDetail({tableData, hideMoorhen, setHideMoorhen, ro } } - document.querySelectorAll("svg")[0].setAttribute("width", "50vw") document.querySelectorAll("svg")[0].setAttribute("height", "100%") }) async function handleContourChange(e) { - map.contourLevel = Number(e.target.value) - await map.doCootContour( - ...map.glRef.current.origin.map(coord => -coord), - map.mapRadius, - map.contourLevel + props.map.contourLevel = Number(e.target.value) + await props.map.doCootContour( + ...props.map.glRef.current.origin.map(coord => -coord), + props.map.mapRadius, + props.map.contourLevel ) } - // useEffect( () => { - // function handleMoorhenResize() { - - // let wWidth = window.innerWidth; - - // if (wWidth < 800) { - // setWidth(wWidth - 200) - // setHeight((wWidth - 200)*0.75) - // console.log("Resizing window to ", wWidth - 100, (wWidth - 100)*0.75) - // } - - // } - // window.addEventListener('resize', handleMoorhenResize) - - // return _ => { - // window.removeEventListener('resize', handleMoorhenResize) - // } - // }) - const [width, setWidth] = useState(900); const [height, setHeight] = useState(600); const [torsionTab, setTorsionTab] = useState(0) return ( -
+
- {/*

Glycan ID: {tableData[rowID].id}

*/}
- +

SNFG

Hover over a linkage to see a summary
@@ -99,11 +75,11 @@ export default function GlycanDetail({tableData, hideMoorhen, setHideMoorhen, ro

Visualise

- + - { + { return [width, height]; }} viewOnly={true}/> @@ -111,7 +87,7 @@ export default function GlycanDetail({tableData, hideMoorhen, setHideMoorhen, ro

Torsion Plots

- +
); } diff --git a/webserver/src/common/Loading.jsx b/webserver/src/components/Loading/Loading.jsx similarity index 100% rename from webserver/src/common/Loading.jsx rename to webserver/src/components/Loading/Loading.jsx diff --git a/webserver/src/common/PageLoad.jsx b/webserver/src/components/Loading/PageLoad.jsx similarity index 100% rename from webserver/src/common/PageLoad.jsx rename to webserver/src/components/Loading/PageLoad.jsx diff --git a/webserver/src/components/Old/BarChart.jsx b/webserver/src/components/Old/BarChart.jsx deleted file mode 100644 index 1f0df4db..00000000 --- a/webserver/src/components/Old/BarChart.jsx +++ /dev/null @@ -1,169 +0,0 @@ -// import { useState, useEffect, useRef } from 'react'; -// import * as d3 from 'd3' - -// export default function BarChart() { - -// const svgRef = useRef(); - -// useEffect(() => { - -// var margin = { top: 20, right: 30, bottom: 30, left: 30 }, -// width = 460 - margin.left - margin.right, -// height = 400 - margin.top - margin.bottom; - -// // append the svg object to the body of the page -// var svg = d3.select("#data") -// .append("svg") -// .attr("width", width + margin.left + margin.right) -// .attr("height", height + margin.top + margin.bottom) -// .append("g") -// .attr("transform", -// "translate(" + margin.left + "," + margin.top + ")") -// let url = "https://raw.githubusercontent.com/glycojones/privateer/master/data/linkage_torsions/unprocessed_files/ASN-NAG_reduced.json" -// fetch(url).then(response => response.json()).then((jsonData) => { - -// var xLim = [-180, 180] -// var yLim = [-180, 180] - -// var x = d3.scaleLinear() -// .nice() -// .domain(xLim) -// .range([0, width]); -// svg.append("g") -// .attr("transform", "translate(0," + height + ")") -// .call(d3.axisBottom(x)); - -// var y = d3.scaleLinear() -// .nice() -// .domain(yLim) -// .range([height, 0]); -// svg.append("g") -// .call(d3.axisLeft(y)); - -// var inputForRectBinning = [] - - -// for (let i = 0; i < jsonData.length; i++) { -// inputForRectBinning.push([+jsonData[i].Phi, +jsonData[i].Psi]) // Note that we had the transform value of X and Y ! -// } - -// console.log(inputForRectBinning) - - -// (function() { -// d3.rectbin = function() { -// var dx = 0.1, -// dy = 0.1, -// x = rectbinX, -// y = rectbinY; - -// function rectbin(points) { -// var binsById = {}; -// var xExtent = d3.extent(points, function(d, i){ return x.call(rectbin, d, i) ;}); -// var yExtent = d3.extent(points, function(d, i){ return y.call(rectbin, d, i) ;}); - -// d3.range(yExtent[0], yExtent[1] + dx, dy).forEach(function(Y){ -// d3.range(xExtent[0], xExtent[1] + dx, dx).forEach(function(X){ -// var py = Y / dy; -// var pj = trunc(py); -// var px = X / dx; -// var pi = trunc(px); -// var id = pi + '-' + pj; -// var bin = binsById[id] = []; -// bin.i = pi; -// bin.j = pj; -// bin.x = pi * dx; -// bin.y = pj * dy; -// }); -// }); -// points.forEach(function(point, i) { -// var py = y.call(rectbin, point, i) / dy; -// var pj = trunc(py); -// var px = x.call(rectbin, point, i) / dx; -// var pi = trunc(px); - -// var id = pi + '-' + pj; -// var bin = binsById[id]; -// bin.push(point); -// }); -// return d3.values(binsById); -// } - -// rectbin.x = function(_) { -// if (!arguments.length) return x; -// x = _; -// return rectbin; -// }; - -// rectbin.y = function(_) { -// if (!arguments.length) return y; -// y = _; -// return rectbin; -// }; - -// rectbin.dx = function(_) { -// if (!arguments.length) return dx; -// dx = _; -// return rectbin; -// }; - -// rectbin.dy = function(_) { -// if (!arguments.length) return dy; -// dy = _; -// return rectbin; -// }; - - -// return rectbin; -// }; - -// var rectbinX = function(d) { return d[0]; }, -// rectbinY = function(d) { return d[1]; }; - -// })(); - -// function trunc(x) { -// return x < 0 ? Math.ceil(x) : Math.floor(x); -// } - -// var size = 0.5 -// var rectbinData = d3.rectbin() -// .dx(size) -// .dy(size) -// (inputForRectBinning) - -// // Prepare a color palette -// var color = d3.scaleLinear() -// .domain([0, 350]) // Number of points in the bin? -// .range(["transparent", "#69a3b2"]) - -// // What is the height of a square in px? -// heightInPx = y(yLim[1] - size) - -// // What is the width of a square in px? -// var widthInPx = x(xLim[0] + size) - -// // Now we can add the squares -// svg.append("clipPath") -// .attr("id", "clip") -// .append("rect") -// .attr("width", width) -// .attr("height", height) -// svg.append("g") -// .attr("clip-path", "url(#clip)") -// .selectAll("myRect") -// .data(rectbinData) -// .enter().append("rect") -// .attr("x", function (d) { return x(d.x) }) -// .attr("y", function (d) { return y(d.y) - heightInPx }) -// .attr("width", widthInPx) -// .attr("height", heightInPx) -// .attr("fill", function (d) { return color(d.length); }) -// .attr("stroke", "black") -// .attr("stroke-width", "0.4") -// }); -// }); - -// return (
) -// } - diff --git a/webserver/src/components/Old/Main.jsx b/webserver/src/components/Old/Main.jsx deleted file mode 100644 index d30739f1..00000000 --- a/webserver/src/components/Old/Main.jsx +++ /dev/null @@ -1,15 +0,0 @@ -import SNFG from './SNFG' - - -export default function Main() { - - - return ( -
- - - -
- ) - -} \ No newline at end of file diff --git a/webserver/src/components/Old/NavBar.jsx b/webserver/src/components/Old/NavBar.jsx deleted file mode 100644 index ddf909f9..00000000 --- a/webserver/src/components/Old/NavBar.jsx +++ /dev/null @@ -1,36 +0,0 @@ -import {GENERAL_CITATION, GITHUB_REPO} from "./Constants" - -export default function NavBar() { - - return ( - - ) -} - - \ No newline at end of file diff --git a/webserver/src/components/Old/SVGCarousel.jsx b/webserver/src/components/Old/SVGCarousel.jsx deleted file mode 100644 index 0c955b72..00000000 --- a/webserver/src/components/Old/SVGCarousel.jsx +++ /dev/null @@ -1,63 +0,0 @@ -import "react-responsive-carousel/lib/styles/carousel.min.css"; -// import { Carousel } from 'react-responsive-carousel'; -import {useCallback, useState} from "react"; - -export default function SVGCarousel({svgs}) { - - let [index, setIndex] = useState(0); - - const next = (() => { - let newIndex = index + 1 - if (newIndex >= svgs.length) { - newIndex = 0; - } - setIndex(newIndex); - - }) - - const prev = (() => { - let newIndex = index - 1 - if (newIndex < 0) { - newIndex = svgs.length - 1 - } - setIndex(newIndex); - }) - - const handleMoorhenClick = ((xyz) => { - // parse_id() - // sendToMoorhen() - }) - - const ref = useCallback((node) => { - let useList = document.querySelectorAll('use') - - for (let i = 0; i < useList.length; i++) { - useList[i].addEventListener("click", (e) => { - console.log(useList[i].id) - }) - } - - document.querySelectorAll("svg")[0].setAttribute("width", "50vw") - document.querySelectorAll("svg")[0].setAttribute("height", "100%") - }) - - return ( -
- -
-

Glycans

-
- -
-
-
- -
- - {index + 1}/{svgs.length} - -
-
- - ); -} \ No newline at end of file diff --git a/webserver/src/common/PDBFetch.jsx b/webserver/src/components/PDBFetch/PDBFetch.jsx similarity index 100% rename from webserver/src/common/PDBFetch.jsx rename to webserver/src/components/PDBFetch/PDBFetch.jsx diff --git a/webserver/src/components/PrivateerDisplay/SNFG.jsx b/webserver/src/components/PrivateerDisplay/SNFG.jsx index 4b9ebd09..b1697f67 100644 --- a/webserver/src/components/PrivateerDisplay/SNFG.jsx +++ b/webserver/src/components/PrivateerDisplay/SNFG.jsx @@ -1,14 +1,10 @@ import {lazy, useEffect, useRef, useState} from "react"; -// import SVGTable from "../SVGTable/SVGTable"; import {MoorhenMap, MoorhenMolecule} from 'moorhen' import GlycanDetail from "../GlycanDetail/GlycanDetail" const SVGTable = lazy(() => import('../SVGTable/SVGTable')); -const initialMoleculesState = [] - -export default function SNFG({tableData, fileName, PDBCode, pdbString, mtzData}) { - +export default function SNFG(props) { const [rowClicked, setRowClicked] = useState(false) const [rowID, setRowID] = useState(0) const [hideMoorhen, setHideMoorhen] = useState(true) @@ -32,10 +28,10 @@ export default function SNFG({tableData, fileName, PDBCode, pdbString, mtzData}) if (cootInitialized && controls.current && !dataLoaded) { setAllowRowClick(true) let newMolecule = new MoorhenMolecule(controls.current.commandCentre, controls.current.glRef, controls.current.monomerLibrary) - newMolecule.loadToCootFromString(pdbString, 'mol-1').then(() => { + newMolecule.loadToCootFromString(props.fileContent, 'mol-1').then(() => { controls.current.changeMolecules({action: 'Add', item: newMolecule}); newMolecule.fetchIfDirtyAndDraw('CBs').then(() => { - let id = tableData[rowID].id + let id = props.tableData[rowID].id let sugar_name = id.split("-")[0] let sugar_id = id.split("-")[1].split("/")[0].split(":")[0] @@ -60,11 +56,11 @@ export default function SNFG({tableData, fileName, PDBCode, pdbString, mtzData}) useWeight: false, calcStructFact: true, } - if (PDBCode == "") { - await map.loadToCootFromMtzData(mtzData, "map-1", mapMetadata) + if (props.PDBCode == "") { + await map.loadToCootFromMtzData(props.mtzData, "map-1", mapMetadata) } else { - await map.loadToCootFromMapData(mtzData, "map-1", false) + await map.loadToCootFromMapData(props.mtzData, "map-1", false) } map.suggestedContourLevel = 0.3 @@ -82,10 +78,9 @@ export default function SNFG({tableData, fileName, PDBCode, pdbString, mtzData}) useEffect(() => { async function move_view() { if (!cootInitialized) {return} - - + setYScrollPosition(window.scrollY) - let id = tableData[rowID].id + let id = props.tableData[rowID].id let sugar_name = id.split("-")[0] let sugar_id = id.split("-")[1].split("/")[0].split(":")[0] let sugar_chain = id.split("/")[1].split("_")[0] @@ -99,27 +94,37 @@ export default function SNFG({tableData, fileName, PDBCode, pdbString, mtzData}) move_view() }, [rowClicked]) + let glycanDetailProps = { + tableData:props.tableData, + hideMoorhen:hideMoorhen, + setHideMoorhen:setHideMoorhen, + rowID:rowID, + forwardControls:forwardControls, + scrollPosition:yScrollPosition, + controls:controls, + molecule:molecule, + map:map + } + + let svgTableProps = { + tableData:props.tableData, + allowRowClick:allowRowClick, + rowClick:rowClicked, + setRowClicked:setRowClicked, + setRowID:setRowID + } + return (
-

Detected {tableData.length} Glycans - in {fileName}

- +

Detected {props.tableData.length} Glycans + in {props.fileName}

+
- +
) diff --git a/webserver/src/common/Submit.jsx b/webserver/src/components/Submit/Submit.jsx similarity index 97% rename from webserver/src/common/Submit.jsx rename to webserver/src/components/Submit/Submit.jsx index ca335760..471d4e11 100644 --- a/webserver/src/common/Submit.jsx +++ b/webserver/src/components/Submit/Submit.jsx @@ -1,4 +1,4 @@ -import Molecule from "../assets/Molecule" +import Molecule from "../../assets/Molecule" function FileLine({icon, name}) { return ( diff --git a/webserver/src/common/Upload.jsx b/webserver/src/components/Upload/Upload.jsx similarity index 60% rename from webserver/src/common/Upload.jsx rename to webserver/src/components/Upload/Upload.jsx index 156d847d..551411f1 100644 --- a/webserver/src/common/Upload.jsx +++ b/webserver/src/components/Upload/Upload.jsx @@ -1,12 +1,9 @@ import { useEffect, useState } from "react"; import UploadButton from "./UploadButton" -import Submit from "./Submit"; -import PDBFetch from "./PDBFetch"; - -export default function Upload({coordinateFile, setCoordinateFile, - reflectionFile, setReflectionFile, - PDBCode, setPDBCode, submitPressed, resetApp, setResetApp}) { +import Submit from "../Submit/Submit"; +import PDBFetch from "../PDBFetch/PDBFetch"; +export default function Upload(props) { const [showUploadAgain, setShowUploadAgain] = useState(true) const [showSubmit, setShowSubmit] = useState(false) const [allowSubmit, setAllowSubmit] = useState(false) @@ -14,50 +11,56 @@ export default function Upload({coordinateFile, setCoordinateFile, useEffect(() => { setShowPDBFetch(true) - }, [resetApp]) + }, [props.resetApp]) useEffect(() => { - if (coordinateFile && reflectionFile) { + if (props.coordinateFile && props.reflectionFile) { setShowSubmit(true) setShowUploadAgain(false) setAllowSubmit(true) setShowPDBFetch(false) } - if (coordinateFile && !reflectionFile) { + if (props.coordinateFile && !props.reflectionFile) { setShowSubmit(true) setShowUploadAgain(true) setAllowSubmit(true) setShowPDBFetch(false) } - if (!coordinateFile && reflectionFile) { + if (!props.coordinateFile && props.reflectionFile) { setShowSubmit(true) setShowUploadAgain(true) setAllowSubmit(false) setShowPDBFetch(false) } - if (!coordinateFile && !reflectionFile) { + if (!props.coordinateFile && !props.reflectionFile) { setShowSubmit(false) setShowUploadAgain(true) setAllowSubmit(false) setShowPDBFetch(true) } - }, [coordinateFile, reflectionFile]) + }, [props.coordinateFile, props.reflectionFile]) return (
- { showUploadAgain == true ? : <>} + { showUploadAgain == true ? : <>} {showSubmit == true ? - : <>} + : <>} {showPDBFetch == true ?
OR
: <>} {showPDBFetch == true ? - + : <>} diff --git a/webserver/src/common/UploadButton.jsx b/webserver/src/components/Upload/UploadButton.jsx similarity index 98% rename from webserver/src/common/UploadButton.jsx rename to webserver/src/components/Upload/UploadButton.jsx index e82714bc..50dc5876 100644 --- a/webserver/src/common/UploadButton.jsx +++ b/webserver/src/components/Upload/UploadButton.jsx @@ -1,6 +1,6 @@ import { useEffect, useState } from "react"; -export default function Upload({setCoordinateFile, setReflectionFile}) { +export default function UploadButton({setCoordinateFile, setReflectionFile}) { const fileUpload = (e) => { if (e.target.files) { diff --git a/webserver/src/layouts/Header.jsx b/webserver/src/layouts/Header.jsx index ab331c32..bd7c102b 100644 --- a/webserver/src/layouts/Header.jsx +++ b/webserver/src/layouts/Header.jsx @@ -1,47 +1,27 @@ import { lazy, Suspense } from 'react' import SNFG from '../components/PrivateerDisplay/SNFG' -// import Upload from "../common/Upload"; -// import Submit from "../common/Submit"; -// import Loading from "../common/Loading"; -import { GITHUB_REPO } from "../data/Constants" -const Upload = lazy(() => import('../common/Upload')); -const Submit = lazy(() => import('../common/Submit')); -const Loading = lazy(() => import('../common/Loading')); +const Upload = lazy(() => import('../components/Upload/Upload')); +const Loading = lazy(() => import('../components/Loading/Loading')); const NavBar = lazy(() => import('../layouts/NavBar')); const NoGlycans = lazy(() => import("../components/NoGlycans/NoGlycans")) -export function Header({ - resetApp, - setResetApp, - PDBCode, - setPDBCode, - coordinateFile, - setCoordinateFile, - reflectionFile, - setReflectionFile, - submit, - setSubmit, - tableData, - loadingText, - fileContent, - fallback, - mtzData, - failureText -}) { +export function Header(props) { + return (
- +
- {fallback != true ? + {props.fallback != true ? }> - {submit == null ? - - : tableData == null ? - : - } + {props.submit == null ? + + : props.tableData == null ? + : + } : }
diff --git a/webserver/src/pages/Home/HomeSection.jsx b/webserver/src/pages/Home/HomeSection.jsx index 43d6f17c..1a071629 100644 --- a/webserver/src/pages/Home/HomeSection.jsx +++ b/webserver/src/pages/Home/HomeSection.jsx @@ -5,65 +5,18 @@ import {Information} from '../../components/Information/Information'; import privateer_module from "../../wasm/privateer.js" import loadGlytoucan from "../../utils/loadGlytoucan" -// import Footer from "../../layouts/Footer" -// import BorderElement from '../../layouts/BorderElement'; const Footer = lazy(() => import('../../layouts/Footer')); const BorderElement = lazy(() => import('../../layouts/BorderElement')); -// const Header = lazy(() => import('../../layouts/Header')); -// const Information = lazy(() => import('../../components/Information/Information')); - -async function fetch_pdb(PDBCode) { - if (PDBCode == null) {return} - console.log("Fetching PDB ", PDBCode) - let mtz_url = `https://edmaps.rcsb.org/coefficients/${PDBCode.toLowerCase()}.mtz` - let pdb_url = `https://files.rcsb.org/download/${PDBCode.toUpperCase()}.pdb` - - let file = fetch(pdb_url) - .then(response => { - if (!response.ok) { - throw new Error('Network error'); - } - return response.text() - }) - .then(file => { - return Promise.resolve(file) - }) - .catch((e) => { - throw new Error("PDB Not Found") - }) - return file -} - -async function fetch_map(PDBCode) { - if (PDBCode == null) {return} - console.log("Fetching MTZ ", PDBCode) - let mtz_url = `https://www.ebi.ac.uk/pdbe/entry-files/${PDBCode.toLowerCase()}.ccp4` - - let file = fetch(mtz_url) - .then(response => { - if (!response.ok) { - throw new Error('Network error'); - } - return response.arrayBuffer() - }) - .then(file => { - return Promise.resolve(file) - }) - .catch((e) => { - throw new Error("PDB Not Found") - }) - return file -} + +import {fetch_map, fetch_pdb} from "../../utils/fetch_from_pdb" export default function HomeSection() { const [coordinateFile, setCoordinateFile] = useState(null); const [reflectionFile, setReflectionFile] = useState(null); const [PDBCode, setPDBCode] = useState("") - const [fileContent, setFileContent] = useState(null) const [mtzData, setMtzData] = useState() - const [submit, setSubmit] = useState(null); const [tableData, setTableData] = useState(null); const [loadingText, setLoadingText] = useState("Validating Glycans..."); @@ -77,6 +30,39 @@ export default function HomeSection() { return new_id } + async function run_privateer(Module, fileContent, name) { + setFileContent(fileContent) + + let x = Module.read_structure_to_table(fileContent, name) + + let table_data = []; + for (var i = 0; i < x.size(); i++) { + let table_entry = x.get(i) + + table_entry.id = sanitize_id(table_entry.id) + + let collected_torsions = [] + for(var j = 0; j < table_entry.torsions.size(); j++) { + collected_torsions.push(table_entry.torsions.get(j)); + } + table_entry.torsions = collected_torsions + table_data.push(table_entry) + + } + + if (x.size() == 0 ) { + setLoadingText("There were no detected glycans in this file.") + setFallBack(true) + } + + // Get Glyconnect ID from WURCS + setLoadingText("Querying Glytoucan...") + await loadGlytoucan(table_data) + + + setTableData(table_data); + } + useEffect(() => { if (PDBCode != "") { setLoadingText(`Fetching ${PDBCode.toUpperCase()} from the PDB`) @@ -92,38 +78,8 @@ export default function HomeSection() { setFileContent(response) setLoadingText("Validating Glycans...") - privateer_module().then(async (Module) => { + privateer_module().then(Module => run_privateer(Module, response, PDBCode)) - let x = Module.read_structure_to_table(response, PDBCode) - - let table_data = []; - for (var i = 0; i < x.size(); i++) { - let table_entry = x.get(i) - - table_entry.id = sanitize_id(table_entry.id) - - let collected_torsions = [] - for(var j = 0; j < table_entry.torsions.size(); j++) { - collected_torsions.push(table_entry.torsions.get(j)); - } - table_entry.torsions = collected_torsions - table_data.push(table_entry) - - } - - if (x.size() == 0 ) { - setFailureText("Privateer could not detect any carbohydrates in this model.") - setLoadingText("There were no detected glycans in this file.") - setFallBack(true) - } - - // Get Glyconnect ID from WURCS - setLoadingText("Querying Glytoucan...") - await loadGlytoucan(table_data) - - - setTableData(table_data); - }) }).catch(e => { setFailureText("This PDB code could not be found") setLoadingText("There were no detected glycans in this file.") @@ -136,39 +92,7 @@ export default function HomeSection() { var coordinateReader = new FileReader(); var reflectionReader = new FileReader(); - coordinateReader.onload = async () => { - - setFileContent(coordinateReader.result) - - let x = Module.read_structure_to_table(coordinateReader.result, coordinateFile.name) - - let table_data = []; - for (var i = 0; i < x.size(); i++) { - let table_entry = x.get(i) - - table_entry.id = sanitize_id(table_entry.id) - - let collected_torsions = [] - for(var j = 0; j < table_entry.torsions.size(); j++) { - collected_torsions.push(table_entry.torsions.get(j)); - } - table_entry.torsions = collected_torsions - table_data.push(table_entry) - - } - - if (x.size() == 0 ) { - setLoadingText("There were no detected glycans in this file.") - setFallBack(true) - } - - // Get Glyconnect ID from WURCS - setLoadingText("Querying Glytoucan...") - await loadGlytoucan(table_data) - - - setTableData(table_data); - } + coordinateReader.onload = () => {run_privateer(Module, coordinateReader.result, coordinateFile.name)} if (coordinateFile) { coordinateReader.readAsText(coordinateFile); @@ -201,15 +125,28 @@ export default function HomeSection() { setPDBCode("") }, [resetApp]) + const main_props = { + resetApp: resetApp, + setResetApp: setResetApp, + PDBCode: PDBCode, + setPDBCode: setPDBCode, + coordinateFile: coordinateFile, + setCoordinateFile: setCoordinateFile, + reflectionFile: reflectionFile, + setReflectionFile: setReflectionFile, + submit: submit, + setSubmit: setSubmit, + tableData: tableData, + loadingText: loadingText, + fileContent: fileContent, + fallback: fallback, + mtzData: mtzData, + failureText: failureText + } + return ( <> -
diff --git a/webserver/src/pages/Main/Main.jsx b/webserver/src/pages/Main/Main.jsx deleted file mode 100644 index 98ce5520..00000000 --- a/webserver/src/pages/Main/Main.jsx +++ /dev/null @@ -1,67 +0,0 @@ -import SNFG from '../../components/SNFG' -import {useEffect, useState} from "react"; -import Upload from "../../components/Upload"; -import Submit from "../../common/Submit"; -import Loading from "../../common/Loading"; -import privateer_module from "../../wasm/privateer.js" -import loadGlytoucan from "../../utils/loadGlytoucan" - -export default function Main({resetApp}) { - - const [file, setFile] = useState(null); - const [fileContent, setFileContent] = useState(null) - const [submit, setSubmit] = useState(null); - // const [svgs, setSVGs] = useState(null); - const [tableData, setTableData] = useState(null); - const [loadingText, setLoadingText] = useState("Validating Glycans..."); - - - useEffect(() => { - privateer_module().then((Module) => { - var reader = new FileReader(); - reader.onload = async () => { - // let x = Module.read_structure(reader.result, file.name) - - // let svgs = []; - // for (var i = 0; i < x.size(); i++) { - // svgs.push(x.get(i)) - // } - // setSVGs(svgs); - setFileContent(reader.result) - let x = Module.read_structure_to_table(reader.result, file.name) - - let table_data = []; - for (var i = 0; i < x.size(); i++) { - table_data.push(x.get(i)) - } - // Get Glyconnect ID from WURCS - setLoadingText("Querying Glytoucan...") - await loadGlytoucan(table_data) - - // setLoadingText("Querying GlyConnect...") - // await load_glyconnect(table_data) - - setTableData(table_data); - } - if (file) { - reader.readAsText(file); - } - }); - }, [submit]) - - useEffect(() => { - setFile(null) - setSubmit(null) - setTableData(null) - }, [resetApp]) - - return ( -
- {file == null ? : - submit == null ? : - tableData == null ? : - - } -
- ) -} \ No newline at end of file diff --git a/webserver/src/utils/fetch_from_pdb.js b/webserver/src/utils/fetch_from_pdb.js new file mode 100644 index 00000000..70fa0394 --- /dev/null +++ b/webserver/src/utils/fetch_from_pdb.js @@ -0,0 +1,42 @@ + +export async function fetch_pdb(PDBCode) { + if (PDBCode == null) {return} + console.log("Fetching PDB ", PDBCode) + let pdb_url = `https://files.rcsb.org/download/${PDBCode.toUpperCase()}.pdb` + + let file = fetch(pdb_url) + .then(response => { + if (!response.ok) { + throw new Error('Network error'); + } + return response.text() + }) + .then(file => { + return Promise.resolve(file) + }) + .catch((e) => { + throw new Error("PDB Not Found") + }) + return file +} + +export async function fetch_map(PDBCode) { + if (PDBCode == null) {return} + console.log("Fetching MTZ ", PDBCode) + let mtz_url = `https://www.ebi.ac.uk/pdbe/entry-files/${PDBCode.toLowerCase()}.ccp4` + + let file = fetch(mtz_url) + .then(response => { + if (!response.ok) { + throw new Error('Network error'); + } + return response.arrayBuffer() + }) + .then(file => { + return Promise.resolve(file) + }) + .catch((e) => { + throw new Error("Map Not Found") + }) + return file +}