From 81a36aabf86fabacdc569224c8a324c36467bf3e Mon Sep 17 00:00:00 2001
From: Remi  PLANEL <rplanel@pasteur.fr>
Date: Thu, 21 Mar 2024 14:24:28 +0100
Subject: [PATCH] try add matrix-pdock auto

---
 components/ServerDbTable.vue        |  25 ------
 components/content/MatrixPdock.vue  | 132 ++++++++++++++++++++++++++++
 content/3.defense-systems/dazbog.md |   1 +
 content/3.defense-systems/pago.md   |   2 +
 nuxt.config.ts                      |   1 +
 server/plugins/content.ts           |  15 ++++
 6 files changed, 151 insertions(+), 25 deletions(-)
 create mode 100644 components/content/MatrixPdock.vue

diff --git a/components/ServerDbTable.vue b/components/ServerDbTable.vue
index 14eebd3e..306f2ee9 100644
--- a/components/ServerDbTable.vue
+++ b/components/ServerDbTable.vue
@@ -126,32 +126,7 @@ onBeforeMount(async () => {
 const msFilterCompo = ref<FilterItem[] | undefined>(undefined)
 
 
-const computedFilterStr = computed(() => {
-    const toValFilters = toValue(msFilterCompo)
-    let filtersStr: string | undefined = undefined
-    if (toValFilters !== undefined && toValFilters.length > 0) {
-        const tmpFilterItems = [...toValFilters]
-        if (tmpFilterItems.length % 4 === 0) {
-            tmpFilterItems.splice(-1)
-        }
-        filtersStr = "(" + tmpFilterItems.map((it, index) => {
-            const sanitizedValue = it.value.split("-").slice(0, -1).join("-")
-            if ((index + 1) % 4 === 3) {
-                return `"${sanitizedValue}"`
-            } else if ((index + 1) % 4 === 0) {
-                return ` ${sanitizedValue} `
-            }
-            else {
-                return `${sanitizedValue}`
-            }
-
-        }).join("") + ")"
 
-    }
-
-    return [filtersStr, props.numericalFilters].filter(f => f !== undefined && f !== null).join(" AND ")
-
-})
 
 
 const computedF = computed(() => toValue(props.numericalFilters))
diff --git a/components/content/MatrixPdock.vue b/components/content/MatrixPdock.vue
new file mode 100644
index 00000000..b2761110
--- /dev/null
+++ b/components/content/MatrixPdock.vue
@@ -0,0 +1,132 @@
+<script setup lang="ts">
+import * as d3 from "d3";
+import * as Plot from "@observablehq/plot";
+import PlotFigure from "~/components/PlotFigure";
+
+
+
+export interface Props {
+    system?: MaybeRef<string | null>
+}
+const { page } = useContent();
+const { system } = withDefaults(defineProps<Props>(), { system: null })
+const dbName = "structure"
+const filterBase = ref<string[]>([
+    "prediction_type='multimer(dimer)'",
+    "completed='true'"
+])
+
+export interface PlotMargin {
+    marginTop: number,
+    marginRight: number,
+    marginBottom: number,
+    marginLeft: number
+}
+
+const margin = ref<PlotMargin>({
+    marginTop: 100,
+    marginRight: 50,
+    marginBottom: 0,
+    marginLeft: 150
+})
+
+const computedSystem = computed(() => {
+    const toValPage = toValue(page)
+    const toValSystem = toValue(system)
+    if (toValSystem === null) {
+        return toValPage?.title?.toLowerCase() ?? null
+    }
+    else {
+        return toValSystem
+    }
+})
+
+
+const groupedPdocks = computed(() => {
+    const toValData = toValue(data)
+    return d3.groups(toValData.hits.flatMap(({ System_name_ok, pDockQ, pdb, nb_sys, proteins_in_the_prediction, system_genes }) => {
+
+
+        if (proteins_in_the_prediction.length === 2) {
+            const sanitizedSystemGenes = system_genes.map(d => d.split("__")[1])
+            const sanitizedProteins = proteins_in_the_prediction.map(d => d.split("__")[1])
+            const setProteins = new Set(sanitizedProteins)
+
+
+            if (setProteins.size === 2) {
+
+                return sanitizedProteins.map((prot, i) => {
+                    if (i === 0) {
+                        return { System_name_ok, system_genes: sanitizedSystemGenes, pDockQ, pdb, nb_sys, proteins_in_the_prediction: sanitizedProteins, protX: prot, protY: sanitizedProteins[i + 1] }
+                    }
+                    else {
+                        return { System_name_ok, system_genes: sanitizedSystemGenes, pDockQ, pdb, nb_sys, proteins_in_the_prediction: sanitizedProteins, protX: prot, protY: sanitizedProteins[i - 1] }
+                    }
+
+                })
+            } else {
+                return { System_name_ok, system_genes: sanitizedSystemGenes, pDockQ, pdb, nb_sys, proteins_in_the_prediction: sanitizedProteins, protX: sanitizedProteins[0], protY: sanitizedProteins[1] }
+            }
+        } else {
+            throw createError(`More than 2 proteins in a dimer structure for system ${computedSystem.value} !`)
+        }
+    }), d => d.system_genes.join("--"))
+})
+
+
+const computedPDocksMatrixPlotOptions = computed(() => {
+    const { marginBottom, marginLeft, marginRight, marginTop } = toValue(margin)
+
+    return toValue(groupedPdocks).map((matrix) => {
+        return {
+            width: matrix[1][0].system_genes.length * 75 + marginLeft + marginRight,
+            height: matrix[1][0].system_genes.length * 75 + marginTop + marginBottom,
+            title: matrix[0],
+            padding: 0,
+            marginTop,
+            marginLeft,
+            marginRight,
+            marginBottom,
+            grid: true,
+
+            x: { axis: "top", label: "Proteins", tickRotate: 45 },
+            y: { label: "Proteins" },
+            legend: { label: matrix[0] },
+            color: { scheme: "plasma", legend: true, reverse: true },
+            marks: [
+                Plot.frame(),
+                Plot.cell(toValue(matrix[1]), {
+                    x: (d) => d.protX,
+                    y: (d) => d.protY,
+                    fill: "pDockQ",
+                    inset: 0.5,
+                    tip: true,
+                    sort: { x: "x", y: "y" }
+                })
+            ]
+        }
+    })
+})
+
+const { data, error } = await useAsyncMeiliSearch({
+    index: toValue(dbName), query: "", params: {
+        facets: ["*"],
+        filter: [
+            `System='${toValue(computedSystem)}'`,
+            ...toValue(filterBase)
+        ],
+    }
+})
+
+if (error.value) {
+    throw createError("Error while getting structure pdocks")
+}
+</script>
+<template>
+    <v-card flat color="transparent">
+        <v-card-text v-if="computedSystem !== null" v-for="option in computedPDocksMatrixPlotOptions"
+            :key="option.legend.label">
+            <PlotFigure :options="unref(option)" defer></PlotFigure>
+        </v-card-text>
+    </v-card>
+</template>
\ No newline at end of file
diff --git a/content/3.defense-systems/dazbog.md b/content/3.defense-systems/dazbog.md
index 09c89773..b8b0edd3 100644
--- a/content/3.defense-systems/dazbog.md
+++ b/content/3.defense-systems/dazbog.md
@@ -59,6 +59,7 @@ dataUrls:
 
 ---
 ::
+
 ##### Example 2
 
 ::molstar-pdbe-plugin
diff --git a/content/3.defense-systems/pago.md b/content/3.defense-systems/pago.md
index e3f7358f..5f012c98 100644
--- a/content/3.defense-systems/pago.md
+++ b/content/3.defense-systems/pago.md
@@ -100,7 +100,9 @@ Proportion of genome encoding the pAgo system for the 14 phyla with more than 50
 
 
 ## Structure
+
 ### pAgo
+
 ##### Example 1
 
 ::molstar-pdbe-plugin
diff --git a/nuxt.config.ts b/nuxt.config.ts
index 3701ae9f..7e0d8d3e 100644
--- a/nuxt.config.ts
+++ b/nuxt.config.ts
@@ -1,6 +1,7 @@
 import { md3 } from 'vuetify/blueprints'
 // https://v3.nuxtjs.org/api/configuration/nuxt.config
 export default defineNuxtConfig({
+  ssr: true,
   modules: [
     '@unocss/nuxt',
     '@nuxt/content',
diff --git a/server/plugins/content.ts b/server/plugins/content.ts
index 52a9870f..c89054e6 100644
--- a/server/plugins/content.ts
+++ b/server/plugins/content.ts
@@ -69,6 +69,21 @@ export default defineNitroPlugin((nitroApp) => {
 
 
                 }
+
+                // add pdock matrix
+
+                // find structure 
+
+                const index = file.body.children.findIndex(child => child.tag === "h2" && child.props.id === "structure")
+                console.log(index)
+                if (index !== -1) {
+                    file.body.children.splice(index, 0, {
+                        type: "element",
+                        tag: 'matrix-pdock',
+                        props: {},
+                        children: []
+                    })
+                }
             }
         })
 })
\ No newline at end of file
-- 
GitLab