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

Merge branch 'list-system-ms' into 'main'

List system ms

See merge request !161
parents 49298b16 9ac175b3
No related branches found
No related tags found
1 merge request!161List system ms
Pipeline #118870 passed with stages
in 8 minutes and 42 seconds
...@@ -3,21 +3,21 @@ import { usePfamStore } from "@/stores/pfam"; ...@@ -3,21 +3,21 @@ import { usePfamStore } from "@/stores/pfam";
const { pfam: pfamStore } = usePfamStore(); const { pfam: pfamStore } = usePfamStore();
export interface Props { export interface Props {
pfamString: string | null; pfams: Record<string, any>[];
itemsToDisplay?: number; itemsToDisplay?: number;
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
pfamString: null, pfams: [],
itemsToDisplay: 2, itemsToDisplay: 2,
}); });
const pfams = computed(() => { // const pfams = computed(() => {
if (props.pfamString === null) { // if (props.pfamString === null) {
return []; // return [];
} else { // } else {
return props.pfamString.split(",").map((pfam) => pfam.trim()); // return props.pfamString.split(",").map((pfam) => pfam.trim());
} // }
}); // });
const show = ref(false); const show = ref(false);
const pfamBaseUrl = ref(new URL("https://www.ebi.ac.uk/interpro/entry/pfam/")); const pfamBaseUrl = ref(new URL("https://www.ebi.ac.uk/interpro/entry/pfam/"));
...@@ -31,11 +31,11 @@ function constructPfamUrl(pfam: string) { ...@@ -31,11 +31,11 @@ function constructPfamUrl(pfam: string) {
<v-col> <v-col>
<v-card flat color="transparent" density="compact" rounded="false"> <v-card flat color="transparent" density="compact" rounded="false">
<template v-for="(pfam, index) in pfams" :key="pfam"> <template v-for="(pfam, index) in pfams" :key="pfam">
<v-chip v-if="index < itemsToDisplay || itemsToDisplay < 0" :href="constructPfamUrl(pfam)" target="_blank" <v-chip v-if="index < itemsToDisplay || itemsToDisplay < 0" :href="constructPfamUrl(pfam.AC)" target="_blank"
color="info" class="mr-1 mb-1"> color="info" class="mr-1 mb-1">
{{ pfam }} {{ pfam.DE }}
<v-tooltip activator="parent" location="top">{{ <v-tooltip activator="parent" location="top">{{
pfamStore.get(pfam)?.DE ?? "none" pfam.AC
}}</v-tooltip></v-chip> }}</v-tooltip></v-chip>
<template v-if="index === itemsToDisplay"> <template v-if="index === itemsToDisplay">
...@@ -51,11 +51,11 @@ function constructPfamUrl(pfam: string) { ...@@ -51,11 +51,11 @@ function constructPfamUrl(pfam: string) {
</template> </template>
<template v-if="pfams.length > itemsToDisplay && show"> <template v-if="pfams.length > itemsToDisplay && show">
<template v-for="(pfam, index) in pfams" :key="pfam"> <template v-for="(pfam, index) in pfams" :key="pfam">
<v-chip v-if="index >= itemsToDisplay" :href="constructPfamUrl(pfam)" target="_blank" color="info" <v-chip v-if="index >= itemsToDisplay" :href="constructPfamUrl(pfam.AC)" target="_blank" color="info"
class="mr-1 mb-1"> class="mr-1 mb-1">
{{ pfam }} {{ pfam.DE }}
<v-tooltip activator="parent" location="top">{{ <v-tooltip activator="parent" location="top">{{
pfamStore.get(pfam)?.DE ?? "none" pfam.AC
}}</v-tooltip></v-chip> }}</v-tooltip></v-chip>
</template> </template>
</template> </template>
......
<script setup lang="ts">
import type { SortItem } from "@/components/ServerDbTable.vue"
import { ServerDbTable } from "#components"
const sortBy: Ref<SortItem[]> = ref([{ key: 'title', order: "asc" }])
const itemValue = ref("title");
const facets: Ref<string[]> = ref(["title", "Sensor", "Activator"])
const headers: Ref<Object[]> = ref([
{ title: "System", key: "title", removable: false },
{ title: "Article", key: "doi", removable: false },
{ title: "Sensor", key: "Sensor", removable: false },
{ title: "Activator", key: "Activator", removable: false },
{ title: "Effector", key: "Effector", removable: false },
{ title: "PFAM", key: "PFAM", removable: false },
{ title: "Contributors", key: "contributors", removable: false },
])
const { search: msSearch, result: msResult } = useMeiliSearch('systems')
const defaultDataTableServerProps = ref({
showExpand: false
})
const dataTableServerProps = computed(() => {
return {
...toValue(defaultDataTableServerProps),
headers: toValue(headers),
itemValue: toValue(itemValue)
}
})
</script>
<template>
<ServerDbTable title="systems" db="systems" :sortBy="sortBy" :facets="facets"
:data-table-server-props="dataTableServerProps">
<template #top>
<v-toolbar><v-toolbar-title class="text-capitalize">
List Systems </v-toolbar-title><v-spacer></v-spacer>
</v-toolbar>
</template>
<template #[`item.title`]="{ item }">
<v-chip color="info" link :to="`/defense-systems/${item.title.toLowerCase()}`">{{
item.title
}}</v-chip>
</template>
<template #[`item.doi`]="{ item }">
<ArticleDoi v-if="item?.doi" :doi="item.doi" :abstract="item?.abstract" :divider="false" :enumerate="false" />
</template>
<template #[`item.PFAM`]="{ item }">
<pfam-chips v-if="item?.PFAM" :pfams="item.PFAM"></pfam-chips>
</template>
</ServerDbTable>
</template>
\ No newline at end of file
...@@ -11,8 +11,8 @@ The knowledge of anti-phage defense systems is ever expanding. The spectacular i ...@@ -11,8 +11,8 @@ The knowledge of anti-phage defense systems is ever expanding. The spectacular i
::system-db
::
......
import typer import typer
import sys import sys
import re import json
import pandas as pd
import shutil import shutil
import csv import csv
import yaml import yaml
...@@ -11,10 +12,6 @@ from pydantic import BaseModel, ValidationError ...@@ -11,10 +12,6 @@ from pydantic import BaseModel, ValidationError
import frontmatter import frontmatter
from enum import Enum from enum import Enum
from rich.console import Console from rich.console import Console
from rich import print as rprint
from rich.layout import Layout
from rich.panel import Panel
console = Console() console = Console()
app = typer.Typer() app = typer.Typer()
...@@ -130,10 +127,8 @@ def structure( ...@@ -130,10 +127,8 @@ def structure(
with open(stat, "r") as stat_f: with open(stat, "r") as stat_f:
reader = csv.DictReader(stat_f) reader = csv.DictReader(stat_f)
for row in reader: for row in reader:
dir_name = system_to_dir[row["system"]] dir_name = system_to_dir[row["system"]]
# console.rule(f"[bold blue]{dir_name}", style="blue")
pdb_path_file = Path(row["pdb"]) pdb_path_file = Path(row["pdb"])
cif_file_name = Path(str(pdb_path_file).split(".pdb")[0] + ".cif") cif_file_name = Path(str(pdb_path_file).split(".pdb")[0] + ".cif")
files = [ files = [
...@@ -157,3 +152,80 @@ def structure( ...@@ -157,3 +152,80 @@ def structure(
console.print( console.print(
f"[red] file {str(file_to_copy.name)} does not exist" f"[red] file {str(file_to_copy.name)} does not exist"
) )
@app.command()
def systems(
dir: Annotated[
Path,
typer.Option(exists=False, file_okay=False, readable=True, dir_okay=True),
],
pfam: Annotated[
Path,
typer.Option(
exists=False,
file_okay=True,
writable=True,
),
],
output: Annotated[
Path,
typer.Option(
file_okay=True,
dir_okay=False,
writable=True,
resolve_path=True,
),
],
):
with open(pfam, "r") as pf:
pfam_df = pd.read_csv(pf, index_col="AC", keep_default_na=False)
systems = []
with open(output, "a") as ty:
for file in dir.iterdir():
if file.suffix == ".md":
console.rule(f"[bold blue]{file.name}", style="blue")
with open(file) as f:
metadata, _ = frontmatter.parse(f.read())
del metadata["layout"]
if "tableColumns" in metadata:
table_data = metadata["tableColumns"]
if "PFAM" in table_data:
# print(table_data["PFAM"])
pfams_list = [
pfam.strip()
for pfam in table_data["PFAM"].split(",")
]
pfam_metadata = list()
for pfam in pfams_list:
try:
pfam_obj = pfam_df.loc[[pfam]]
# print(pfam_obj)
pfam_to_dict = pfam_obj.to_dict(orient="index")
pfam_to_dict[pfam]["AC"] = pfam
flatten_value = pfam_to_dict[pfam]
pfam_metadata.append(flatten_value)
except KeyError as err:
console.print(f"[bold red]{err}", style="red")
console.print(
f"[bold red]No pfam entry or {pfam}",
style="red",
)
continue
del metadata["tableColumns"]
if "article" in table_data:
metadata["doi"] = table_data["article"]["doi"]
if "abstract" in table_data["article"]:
metadata["abstract"] = table_data["article"][
"abstract"
]
del table_data["article"]
sanitizedMetadata = {**metadata, **table_data}
sanitizedMetadata["PFAM"] = pfam_metadata
systems.append(sanitizedMetadata)
json_object = json.dumps(systems, indent=2)
ty.write(json_object)
import meilisearch import meilisearch
from pathlib import Path from pathlib import Path
import csv import csv
import json
from typing import Annotated, List, Optional from typing import Annotated, List, Optional
from pydantic import BaseModel, Field, BeforeValidator from pydantic import BaseModel, Field, BeforeValidator
from enum import Enum from enum import Enum
...@@ -175,6 +175,37 @@ def update_structure( ...@@ -175,6 +175,37 @@ def update_structure(
index.update_typo_tolerance({"enabled": False}) index.update_typo_tolerance({"enabled": False})
def update_systems(
host: str,
key: str,
file: Path,
document: str,
):
client = meilisearch.Client(host, key)
index = client.index(document.lower())
with open(file, "r") as jsonfile:
json_object = json.load(jsonfile)
tasks = index.add_documents_in_batches(json_object, primary_key="title")
for task in tasks:
print(task)
pagination_settings_task = index.update_pagination_settings(
{"maxTotalHits": 100000}
)
print(pagination_settings_task)
attr_task = index.update_filterable_attributes(
body=["title", "Sensor", "Activator", "Effector", "PFAM.AC"]
)
params = {
"maxValuesPerFacet": 1000000,
"sortFacetValuesBy": {"*": "count"},
}
index.update_faceting_settings(params)
print(attr_task)
index.update_sortable_attributes(["title", "Sensor", "Activator", "Effector"])
index.update_typo_tolerance({"enabled": False})
def split_on_comma(str_val: str) -> List[str]: def split_on_comma(str_val: str) -> List[str]:
for val in str_val.split(","): for val in str_val.split(","):
yield val.strip() yield val.strip()
...@@ -2,7 +2,7 @@ import typer ...@@ -2,7 +2,7 @@ import typer
import meilisearch import meilisearch
from typing_extensions import Annotated from typing_extensions import Annotated
from pathlib import Path from pathlib import Path
from df_wiki_cli.meilisearch import update_refseq, update_structure from df_wiki_cli.meilisearch import update_refseq, update_structure, update_systems
from enum import Enum from enum import Enum
from types import SimpleNamespace from types import SimpleNamespace
...@@ -12,6 +12,7 @@ app = typer.Typer() ...@@ -12,6 +12,7 @@ app = typer.Typer()
class Documents(str, Enum): class Documents(str, Enum):
refseq = "refseq" refseq = "refseq"
structure = "structure" structure = "structure"
systems = "systems"
@app.callback() @app.callback()
...@@ -54,6 +55,8 @@ def update( ...@@ -54,6 +55,8 @@ def update(
update_refseq(ctx.obj.host, ctx.obj.key, file, document) update_refseq(ctx.obj.host, ctx.obj.key, file, document)
if document == "structure": if document == "structure":
update_structure(ctx.obj.host, ctx.obj.key, file, document) update_structure(ctx.obj.host, ctx.obj.key, file, document)
if document == "systems":
update_systems(ctx.obj.host, ctx.obj.key, file, document)
@app.command() @app.command()
......
...@@ -26,7 +26,10 @@ def fetch_pfam(output): ...@@ -26,7 +26,10 @@ def fetch_pfam(output):
else: else:
kk, v = line.split(" ") kk, v = line.split(" ")
g, k = kk.split() g, k = kk.split()
d[pfID][k] = v if (k == 'AC'):
d[pfID][k] = v.split(".")[0]
else:
d[pfID][k] = v
df = pd.DataFrame(d).T df = pd.DataFrame(d).T
df.index.name = "ID" df.index.name = "ID"
......
<script setup lang="ts">
import { useDisplay, useLayout } from "vuetify";
const { height } = useDisplay();
// const { getLayoutItem } = useLayout()
// console.log(getLayoutItem('app-bar'))
const { data, error, pending } = await useAsyncData(
"list-defense-systems",
() => queryContent("/defense-systems").where({ _partial: false }).find()
);
const defaultHeaders = ref([{ title: "System", key: "system" }]);
const tableKey = "tableColumns";
const sanitizedData = computed(() => {
if (data?.value && data.value?.length > 0) {
return data.value?.filter((entry) => {
if (entry._dir === "old" || entry._dir === "") {
return false;
}
return true;
});
} else {
return [];
}
});
const headers = computed(() => {
const uniqHeaders = Array.from(
sanitizedData.value.reduce((headerSet, df) => {
if (df?.[tableKey]) {
return new Set([...headerSet, ...Object.keys(df[tableKey])]);
} else {
return headerSet;
}
}, new Set())
);
return [
...defaultHeaders.value,
...uniqHeaders.map((value) => {
return { title: value, key: value };
}),
];
});
const systems = computed(() => {
return sanitizedData.value.map((content) => {
return {
system: { name: content.title, path: content._path },
...content[tableKey],
};
});
});
</script>
<template>
<v-card flat color="transparent">
<ListSystems :headers="headers" :systems="systems" :height="height - 220"></ListSystems>
</v-card>
</template>
\ No newline at end of file
source diff could not be displayed: it is too large. Options to address this: view the blob.
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment