Skip to content
Snippets Groups Projects
Commit 4ec146d7 authored by Remi  PLANEL's avatar Remi PLANEL
Browse files

add a pae viewer

parent db2b9d65
No related branches found
No related tags found
1 merge request!134Resolve "Table with all PDB files, to make them available to download"
<script setup lang="ts"> <script setup lang="ts">
import { withTrailingSlash, withLeadingSlash, joinURL } from 'ufo' import { withTrailingSlash, withLeadingSlash, joinURL } from 'ufo'
import { useRuntimeConfig, computed } from '#imports' import { useRuntimeConfig, computed } from '#imports'
import * as d3 from "d3";
import * as Plot from "@observablehq/plot";
import PlotFigure from "~/components/PlotFigure";
export interface Props { export interface Props {
height?: number height?: number
dataUrls?: string[] dataUrls?: string[]
...@@ -47,8 +54,8 @@ const dialog = ref(false) ...@@ -47,8 +54,8 @@ const dialog = ref(false)
// const show = ref(false) // const show = ref(false)
const computedWidth = computed(() => { const computedWidth = computed(() => {
if (width > maxWidth) return maxWidth // if (toValue(width) > toValue(maxWidth)) return toValue(maxWidth) / 1.5
return width return toValue(width) / 1.5
}) })
const computedHeight = computed(() => { const computedHeight = computed(() => {
...@@ -90,6 +97,45 @@ const pdbeMolstarComponent = ref(null) ...@@ -90,6 +97,45 @@ const pdbeMolstarComponent = ref(null)
// const selectedPdb = ref("/wiki/avs/AVAST_I,AVAST_I__Avs1A,0,V-plddts_85.07081.pdb") // const selectedPdb = ref("/wiki/avs/AVAST_I,AVAST_I__Avs1A,0,V-plddts_85.07081.pdb")
const selectedPdb = ref(null) const selectedPdb = ref(null)
const selectedPaePath = computed(() => {
return selectedPdb.value ? `${selectedPdb.value.split(".").slice(0, -1).join('.')}.tsv` : null
})
const paeData = ref([])
watch(selectedPaePath, async (newPaePath) => {
if (newPaePath !== null) {
const data = await d3.tsv(newPaePath);
// console.log(data)
paeData.value = data
} else {
paeData.value = []
}
})
const sanitizedPaeData = computed(() => {
return paeData.value.reduce((acc, curr, index) => {
const scoredResidu = index
for (const [alignedResidu, value] of Object.entries(curr)) {
// console.log(value)
acc.push({ alignedResidu: parseInt(alignedResidu), scoredResidu: parseInt(scoredResidu), value: parseFloat(value) })
}
return acc
}, [])
})
const plotPaeOptions = computed(() => {
return {
color: { scheme: "Greens", legend: true, reverse: true, label: "Expected position error (Ångströms)" },
y: { reverse: true },
marks: [
Plot.dot(sanitizedPaeData.value, { x: "scoredResidu", y: "alignedResidu", stroke: "value" })
]
}
})
watch(selectedPdb, (selectedPdb, prevSelectPdb) => { watch(selectedPdb, (selectedPdb, prevSelectPdb) => {
if (selectedPdb !== null) { if (selectedPdb !== null) {
dialog.value = true dialog.value = true
...@@ -130,13 +176,18 @@ watch(selectedPdb, (selectedPdb, prevSelectPdb) => { ...@@ -130,13 +176,18 @@ watch(selectedPdb, (selectedPdb, prevSelectPdb) => {
</v-toolbar> </v-toolbar>
<v-card-text> <v-card-text>
<v-row>
<v-sheet v-if="selectedPdb" <v-sheet v-if="selectedPdb"
class="d-flex align-center justify-center flex-wrap text-center mx-auto px-4 my-3" class="d-flex align-center justify-center flex-wrap text-center mx-auto px-4 my-3"
:height="computedHeight" :max-width="maxWidth" :width="computedWidth" position="relative"> :height="computedHeight" :width="computedWidth" position="relative">
<pdbe-molstar ref="pdbeMolstarComponent" hide-controls="true" landscape="true" :custom-data-url="selectedPdb" alphafold-view="true" <pdbe-molstar ref="pdbeMolstarComponent" hide-controls="true" landscape="true"
custom-data-format="pdb"></pdbe-molstar> :custom-data-url="selectedPdb" alphafold-view="true"
custom-data-format="cif"></pdbe-molstar>
</v-sheet> </v-sheet>
<v-col v-if="sanitizedPaeData?.length > 0">
<PlotFigure defer :options="plotPaeOptions"></PlotFigure>
</v-col>
</v-row>
</v-card-text> </v-card-text>
</v-card> </v-card>
......
...@@ -33,8 +33,14 @@ const dataTableServerProps = computed(() => { ...@@ -33,8 +33,14 @@ const dataTableServerProps = computed(() => {
}) })
function namesToCollapsibleChips(names: string[]) { function namesToCollapsibleChips(names: string[]) {
return names.filter((it) => it !== "").map(it => ({ title: it })) return names.filter((it) => it !== "").map(it => ({ title: it.split("__").pop() }))
} }
function pdbNameToCif(pdbPath: string) {
const cifPath = pdbPath.split(".").slice(0, -1).join(".")
return `${cifPath}.cif`
}
</script> </script>
<template> <template>
<ServerDbTable title="Predicted Structures" db="structure" :sortBy="sortBy" :facets="facets" <ServerDbTable title="Predicted Structures" db="structure" :sortBy="sortBy" :facets="facets"
...@@ -50,7 +56,7 @@ function namesToCollapsibleChips(names: string[]) { ...@@ -50,7 +56,7 @@ function namesToCollapsibleChips(names: string[]) {
<td :colspan="columns.length"> <td :colspan="columns.length">
<v-card flat color="transparent"> <v-card flat color="transparent">
<v-card-text> <v-card-text>
<MolstarPdbePlugin :data-urls="[`/${item.system.toLowerCase()}/${item.pdb}`]"> <MolstarPdbePlugin :data-urls="[`/${item.system.toLowerCase()}/${pdbNameToCif(item.pdb)}`]">
</MolstarPdbePlugin> </MolstarPdbePlugin>
</v-card-text> </v-card-text>
</v-card> </v-card>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment