<script setup lang="ts"> import * as Plot from "@observablehq/plot"; import PlotFigure from "~/components/PlotFigure"; import type { SortItem } from "@/components/ServerDbTable.vue" import { useNumericalFilter } from "@/composables/useNumericalfilter" import { ServerDbTable } from "#components" const sortBy: Ref<SortItem[]> = ref([{ key: 'system', order: "asc" }]) const itemValue = ref("id"); const facets: Ref<string[]> = ref(["system", "completed", "prediction_type",]) const headers: Ref<Object[]> = ref([ { title: 'Structure', key: 'structure', sortable: false, removable: false }, { title: "Type", key: "system", removable: false }, // { title: "pdb file", key: "pdb" }, // { title: "fasta", key: "fasta_file" }, { title: "Proteins in structure", key: 'proteins_in_the_prediction', sortable: false, removable: true }, { title: "System genes", key: "system_genes", sortable: false, removable: true }, { title: "Sys id", key: "nb_sys", removable: true }, { title: "Completed", key: "completed", removable: true }, { title: "Prediction type", key: "prediction_type", removable: true }, { title: "N genes in sys", key: "system_number_of_genes", removable: true }, { title: "pLDDT", key: "plddts", removable: true }, { title: "iptm+ptm", key: "iptm+ptm", removable: true }, { title: "pDockQ", key: "pDockQ", removable: true }, // { title: "Type", key: "type", removable: true }, ]) const { search: msSearch, result: msResult } = useMeiliSearch('structure') const { range: plddtsRange, stringifyFilter: plddtsFilter, reset: plddtsReset } = useNumericalFilter("plddts", 0, 100) const { range: iptmRange, stringifyFilter: iptmFilter, reset: iptmReset } = useNumericalFilter("iptm+ptm", 0, 1) const { range: pdockqRange, stringifyFilter: pdockqFilter, reset: pdockqReset } = useNumericalFilter("pDockQ", 0, 1) const numericalFilters = computed(() => { const listFilters = [plddtsFilter, iptmFilter, pdockqFilter].map(f => toValue(f)).filter(f => f !== undefined) return listFilters.length > 0 ? listFilters.join(" AND ") : undefined }) const defaultDataTableServerProps = ref({ showExpand: false }) const dataTableServerProps = computed(() => { return { ...toValue(defaultDataTableServerProps), headers: toValue(headers), itemValue: toValue(itemValue) } }) function namesToCollapsibleChips(names: string[], file: string | null = null) { if (file === null) { return names.filter((it) => it !== "").map(it => ({ title: it.split("__").pop() })) } else { return names.filter((it) => it !== "").map(it => ({ title: it.split("__").pop(), href: `/wiki/${toSystemName(file)}/${file}` })) } } function pdbNameToCif(pdbPath: string) { const cifPath = pdbPath.split(".").slice(0, -1).join(".") return `${cifPath}.cif` } function toSystemName(rawName: string) { // split on -0 if exists else on _ if (rawName.includes("-0")) { return rawName.split("-0")[0].toLocaleLowerCase() } else { return rawName.split("_")[0].toLocaleLowerCase() } } const plddtDistribution = computed(() => { if (toValue(msResult)?.facetDistribution?.plddts) { return Object.entries(toValue(msResult).facetDistribution.plddts).map(([key, value]) => { }) } }) </script> <template> <ServerDbTable title="Predicted Structures" db="structure" :sortBy="sortBy" :facets="facets" :data-table-server-props="dataTableServerProps" :numerical-filters="numericalFilters"> <template #numerical-filters="{ search }"> <v-row> <v-col md="12" lg="4"> <v-range-slider v-model="plddtsRange" strict density="compact" hide-details="auto" label="pLDDT" step="0.5" :min="0" :max="100" thumb-label="always" @update:modelValue="search()"> <template #append> <v-btn variant="text" icon="md:restart_alt" @click="plddtsReset()"></v-btn> </template> </v-range-slider> </v-col> <v-col md="12" lg="4"> <v-range-slider v-model="iptmRange" strict density="compact" hide-details="auto" label="iptm+ptm" step="0.1" :min="0" :max="1" thumb-label="always" @update:modelValue="search()"> <template #append> <v-btn variant="text" icon="md:restart_alt" @click="iptmReset()"></v-btn> </template> </v-range-slider> </v-col> <!-- pdockqReset --> <v-col md="12" lg="4"> <v-range-slider v-model="pdockqRange" strict density="compact" hide-details="auto" label="pDockQ" step="0.1" :min="0" :max="1" thumb-label="always" @update:modelValue="search()"> <template #append> <v-btn variant="text" icon="md:restart_alt" @click="pdockqReset()"></v-btn> </template> </v-range-slider> </v-col> </v-row> </template> <template #[`item.proteins_in_the_prediction`]="{ item }"> <CollapsibleChips :items="namesToCollapsibleChips(item.proteins_in_the_prediction, item.fasta_file)"> </CollapsibleChips> </template> <template #[`item.system_genes`]="{ item }"> <CollapsibleChips :items="namesToCollapsibleChips(item.system_genes)"></CollapsibleChips> </template> <template #[`item.structure`]="{ item }"> <MolstarPdbePlugin v-if="item?.pdb && item.pdb !== 'na'" :data-urls="[`/${toSystemName(item.system)}/${pdbNameToCif(item.pdb)}`]" uniq> </MolstarPdbePlugin> <span v-else class="d-flex flex-wrap align-center justify-center"> <v-icon color="warning" icon="md:dangerous"></v-icon> </span> </template> <template #[`item.completed`]="{ item }"> <v-icon v-if="item.completed" color="success" icon="md:check"></v-icon> <v-icon v-else color="warning" icon="md:dangerous"></v-icon> </template> </ServerDbTable> </template>