Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • mdm-lab/wiki
  • hvaysset/wiki
  • jsousa/wiki
  • tclabby/wiki
4 results
Show changes
Commits on Source (34)
Showing
with 450 additions and 269 deletions
......@@ -38,7 +38,9 @@ function onScroll() {
<v-row justify="center">
<v-col cols="auto">
<v-card flat color="transparent" :min-width="mobile ? undefined : 900" :max-width="fluid ? undefined : 1500">
<slot />
<v-card-text>
<slot />
</v-card-text>
<EditGitlab v-if="edit" />
<NavPrevNext v-if="edit" />
</v-card>
......
......@@ -2,9 +2,10 @@
// import type { FacetDistribution } from "meilisearch";
import { useSlots } from 'vue'
import { useDisplay } from "vuetify";
import { useFacetsStore } from '~~/stores/facets'
import * as Plot from "@observablehq/plot";
import PlotFigure from "~/components/PlotFigure";
import * as d3 from "d3";
import { useThrottleFn } from '@vueuse/core'
import { useMeiliSearch } from "#imports"
export interface SortItem {
key: string,
......@@ -36,17 +37,15 @@ const props = withDefaults(defineProps<Props>(), {
console.log(props.dataTableServerProps)
const slots = useSlots()
const sortByRef = toRef(props.sortBy)
const facetsRef = toRef(props.facets)
const emit = defineEmits(["refresh:search"])
const { search: msSearch, result: msResult } = useMeiliSearch(props.db)
const facetStore = useFacetsStore()
const search: Ref<string> = ref("");
const filterOrSearch: Ref<FilterItem[] | null> = ref(null)
const hitsPerPage: Ref<number> = ref(25)
const itemsPerPage: Ref<number[]> = ref([25, 50, 100])
const filterError: Ref<string | null> = ref(null)
const msFilter: Ref<string | undefined> = ref(undefined)
const page = ref(1)
......@@ -58,6 +57,7 @@ const computedTableHeight = computed(() => {
const computedHeight = height.value - 350
return computedHeight > minTableHeight.value ? computedHeight : minTableHeight.value
})
const plddtRange = ref([0, 100])
// const { pending: pendingDownloadData, downloadCsv } = useCsvDownload(props.db, `df-${props.db}`)
......@@ -126,7 +126,40 @@ watch([paginationParams, msSortBy, page], ([newParams, newSort, newPage]) => {
onMounted(async () => {
searchOrFilter()
})
const hasPlddt = computed(() => props.db === 'structure')
// Fetch results
const plddtFilter = computed(() => {
const plddtRangeValue = plddtRange.value
if (hasPlddt.value && plddtRangeValue?.length === 2) {
return `plddts ${plddtRangeValue[0]} TO ${plddtRangeValue[1]}`
} else {
return undefined
}
})
const computedFilter = computed(() => {
if (toValue(msFilter)) {
if (toValue(plddtFilter)) {
return `${toValue(msFilter)} AND ${toValue(plddtFilter)}`
}
else {
return toValue(msFilter)
}
} else {
if (toValue(plddtFilter)) {
return `${toValue(plddtFilter)}`
}
else {
return undefined
}
}
})
const msError = computed(() => {
if (filterError.value?.type && filterError.value?.message) {
......@@ -134,16 +167,26 @@ const msError = computed(() => {
} else { return false }
})
const throttleSearch = useThrottleFn(async () => { searchOrFilter() }, 300)
async function searchOrFilter(pagination = true) {
// do something, it will be called at most 1 time per second
try {
loading.value = true
// const q = queryInputValue.value === null ? "" : queryInputValue.value
const q = search.value
emit("refresh:search", {
index: props.db,
query: q,
params: { ...notPaginatedParams.value, filter: toValue(computedFilter), sort: msSortBy.value }
})
if (pagination) {
await msSearch(q, { ...paginationParams.value, filter: msFilter.value, sort: msSortBy.value })
await msSearch(q, { ...paginationParams.value, filter: toValue(computedFilter), sort: msSortBy.value })
}
else {
await msSearch(q, { ...notPaginatedParams.value, filter: msFilter.value, sort: msSortBy.value })
await msSearch(q, { ...notPaginatedParams.value, filter: toValue(computedFilter), sort: msSortBy.value })
}
} catch (error: any) {
......@@ -153,9 +196,11 @@ async function searchOrFilter(pagination = true) {
finally {
loading.value = false
}
}
function clearFilterOrSearch() {
filterOrSearch.value = null
searchOrFilter()
......@@ -167,11 +212,6 @@ watch(msFilter, async (fos) => {
})
watch(msResult, (newRes) => {
facetStore.setFacets({ facetDistribution: newRes.facetDistribution, facetStat: newRes.facetStat })
}, { deep: true })
const totalHits = computed(() => {
return toValue(msResult)?.totalHits ?? toValue(msResult)?.estimatedTotalHits ?? 0
......@@ -195,7 +235,7 @@ watch(filterInputValues, (newSoF) => {
})
watch(search, () => { searchOrFilter() })
// watch(plddtRange, () => { searchOrFilter() })
const filterStep = computed(() => {
return filterInputValues.value !== null && filterInputValues.value.length > 0 ? filterInputValues.value?.length % 3 : null
})
......@@ -239,7 +279,7 @@ const autocompleteItems = computed(() => {
const { type, value } = filterOrSearch.value?.slice(-2, -1)[0]
const sanitizedValue = value.split("-")[0]
// console.log("compute new facets")
const facetDistri = facetStore.facets?.facetDistribution
const facetDistri = msResult.value?.facetDistribution
// console.log(facetDistri)
return facetDistri?.[sanitizedValue] ? Object.entries(facetDistri[sanitizedValue]).map(([key, val]) => {
return {
......@@ -276,32 +316,19 @@ function clearSearch() {
// function runTextSearch() {
// if (canAddTextSearch) {
// const item: FilterItem = reactive({
// type: 'text', title: search.value, value: search.value, deletable: true, props: { type: "text", deletable: true, }
// })
// if (Array.isArray(filterOrSearch.value)) {
// filterOrSearch.value = [
// ...filterOrSearch.value, item
// ]
// } else {
// filterOrSearch.value = [item]
// }
// search.value = ""
// searchOrFilter()
// }
// }
// const groupSortDomain = computed(() => {
// console.log(msResult.value)
// return msResult.value ? d3.groupSort(msResult.value?.hits?.filter((d) => d.phylum), (g) => d3.median(g, (d) => d.phylum), (d) => d.type) : []
// })
// function downloadData() {
// downloadCsv(search, msFilter, msSortBy, notPaginatedParams)
// }
</script>
<template>
<v-card flat color="transparent">
<v-card-text>
</v-card-text>
<v-card-text>
<v-row>
<v-col cols="5">
......@@ -327,23 +354,28 @@ function clearSearch() {
</v-autocomplete>
</v-col>
</v-row>
<v-row v-if="props.db === 'structure'">
<v-col>
<v-range-slider v-model="plddtRange" density="compact" hide-details="auto" label="pLDDT" step="0.1"
@update:modelValue="throttleSearch()">
<template v-slot:prepend>
<span hide-details single-line type="number" variant="outlined" density="compact"
style="width: 70px">{{ plddtRange[0] }}</span>
</template>
<template v-slot:append>
<span hide-details single-line type="number" variant="outlined" style="width: 70px"
density="compact">{{ plddtRange[1] }}</span>
</template>
</v-range-slider>
</v-col>
</v-row>
</v-card-text>
<v-data-table-server v-if="!msError" v-model:page="page" color="primary" v-bind="dataTableServerProps"
v-model:items-per-page="hitsPerPage" v-model:sortBy="sortByRef" v-model:expanded="expanded" fixed-header
:loading="loading" :items="msResult?.hits ?? []" :items-length="totalHits" density="compact"
:height="computedTableHeight" class="elevation-1 mt-2">
<template #top>
<v-toolbar><v-toolbar-title class="text-capitalize">
{{ props.db }}
</v-toolbar-title><v-spacer></v-spacer>
<!-- <v-btn :loading="pendingDownloadData" :disabled="totalHits > 10000" @click="downloadData" icon
variant="text" class="text-none mr-15">
<v-badge :content="totalHits" color="info" floating>
<v-icon>md:download</v-icon></v-badge></v-btn> -->
</v-toolbar>
</template>
:items-per-page-options="itemsPerPage" :height="computedTableHeight" class="elevation-1 mt-2">
<template v-for="(slot, index) of Object.keys(slots)" :key="index" v-slot:[slot]="data">
<slot :name="slot" v-bind="data"></slot>
</template>
......
......@@ -12,6 +12,7 @@ export interface Props {
height?: number
dataUrls?: string[]
dataUrl?: string
uniq?: boolean
}
// const selectedPdb = ref('')
const refinedDataUrls = computed(() => {
......@@ -44,6 +45,7 @@ const refinedDataUrls = computed(() => {
// const selectedPdb = ref(refinedDataUrls.value?.length > 0 ? refinedDataUrls.value[0] : null)
const props = withDefaults(defineProps<Props>(), {
height: 600,
uniq: false
})
const { width, height } = useDisplay()
......@@ -95,7 +97,7 @@ useHead({
const pdbeMolstarComponent = ref(null)
// const selectedPdb = ref("/wiki/avs/AVAST_I,AVAST_I__Avs1A,0,V-plddts_85.07081.pdb")
const selectedPdb = ref(null)
const selectedPdb: Ref<string | null> = ref(null)
const selectedPaePath = computed(() => {
return selectedPdb.value ? `${selectedPdb.value.split(".").slice(0, -1).join('.')}.tsv` : null
......@@ -160,23 +162,29 @@ const plotPaeOptions = computed(() => {
})
watch(selectedPdb, (newSelectedPdb, prevSelectPdb) => {
if (newSelectedPdb !== null) {
viewPdb(newSelectedPdb)
})
function viewPdb(pdbPath: string | null) {
if (pdbPath !== null) {
dialog.value = true
const format = toValue(newSelectedPdb)?.split(".").slice(-1)[0]?.toLowerCase() ?? "pdb"
const format = toValue(pdbPath)?.split(".").slice(-1)[0]?.toLowerCase() ?? "pdb"
moleculeFormat.value = format
if (pdbeMolstarComponent.value?.viewerInstance) {
const viewerInstance = pdbeMolstarComponent.value.viewerInstance
// show.value = true
const customData = { url: newSelectedPdb, format: format, binary: false }
const customData = { url: pdbPath, format: format, binary: false }
viewerInstance.visual.update({ customData })
}
}
}
function setSelectedPdbToFirst() {
const urls = toValue(refinedDataUrls)
if (urls.length >= 1) {
selectedPdb.value = urls[0]
}
})
}
// const moleculeFormat = computed(() => {
// return toValue(selectedPdb)?.split(".")?.[-1]?.toLowerCase() ?? "pdb"
......@@ -186,10 +194,13 @@ const moleculeFormat: Ref<string> = ref("pdb")
<template>
<v-row><v-col><v-select v-model="selectedPdb" label="Select PDB" :items="refinedDataUrls"
hide-details="auto"></v-select></v-col></v-row>
<span class="d-flex flex-wrap align-center justify-center">
<v-col>
<v-btn v-if="uniq" size="x-small" variant="tonal" icon="md:visibility" @click="setSelectedPdbToFirst()"></v-btn>
<v-select v-else v-model="selectedPdb" label="Select PDB" :items="refinedDataUrls" hide-details="auto">
</v-select>
</v-col>
<v-row justify="center">
<v-dialog v-model="dialog" transition="dialog-bottom-transition" fullscreen :scrim="false">
<v-card flat :rounded="false">
<v-toolbar>
......@@ -218,7 +229,7 @@ const moleculeFormat: Ref<string> = ref("pdb")
<v-col>
<PlotFigure v-if="sanitizedPaeData?.length > 0 && paeError === null" defer
:options="plotPaeOptions"></PlotFigure>
<v-alert v-else type="warning">{{ paeError }}</v-alert>
<v-alert v-else type="warning" variant="tonal">{{ paeError }}</v-alert>
<v-card flat color="transparent">
<v-card-title>Model Confidence</v-card-title>
......@@ -269,35 +280,12 @@ const moleculeFormat: Ref<string> = ref("pdb")
</v-list-item>
</v-list>
</v-card>
<!-- <div _ngcontent-ykv-c96="" class="confidenceWrapper">
<div _ngcontent-ykv-c96="" class="column legendRow ng-star-inserted"><span
_ngcontent-ykv-c96="" class="legendColor"
style="background-color: rgb(0, 83, 214);">&nbsp;</span><span _ngcontent-ykv-c96=""
class="legendlabel">Very high (pLDDT &gt; 90)</span></div>
<div _ngcontent-ykv-c96="" class="column legendRow ng-star-inserted"><span
_ngcontent-ykv-c96="" class="legendColor"
style="background-color: rgb(101, 203, 243);">&nbsp;</span><span
_ngcontent-ykv-c96="" class="legendlabel">High (90 &gt; pLDDT &gt; 70)</span></div>
<div _ngcontent-ykv-c96="" class="column legendRow ng-star-inserted"><span
_ngcontent-ykv-c96="" class="legendColor"
style="background-color: rgb(255, 219, 19);">&nbsp;</span><span
_ngcontent-ykv-c96="" class="legendlabel">Low (70 &gt; pLDDT &gt; 50)</span></div>
<div _ngcontent-ykv-c96="" class="column legendRow ng-star-inserted"><span
_ngcontent-ykv-c96="" class="legendColor"
style="background-color: rgb(255, 125, 69);">&nbsp;</span><span
_ngcontent-ykv-c96="" class="legendlabel">Very low (pLDDT &lt; 50)</span></div> -->
<!---->
<!-- </div> -->
<!-- <div _ngcontent-ykv-c96="" class="column legendDesc"> AlphaFold produces a per-residue model
confidence score (pLDDT) between 0 and 100. Some regions below 50 pLDDT may be unstructured
in isolation. </div> -->
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-dialog>
</v-row>
</span>
</template>
......
<script setup lang="ts">
import { useFacetsStore } from '~~/stores/facets'
import * as Plot from "@observablehq/plot";
import PlotFigure from "~/components/PlotFigure";
import { useDisplay } from "vuetify";
import type { SortItem } from "@/components/ServerDbTable.vue"
import { ServerDbTable } from "#components"
const facetStore = useFacetsStore()
const sortBy: Ref<SortItem[]> = ref([{ key: 'type', order: "asc" }])
const itemValue = ref("id");
const { width } = useDisplay();
const distriTool: Ref<string[]> = ref([])
const scaleTransform: Ref<string[]> = ref([])
const facets = ref([
"replicon",
......@@ -50,11 +48,9 @@ const headers = ref([
sortable: false
}
])
const logTransform = computed(() => {
return distriTool.value.includes('log')
})
const fullWidth = computed(() => {
return distriTool.value.includes('fullwidth')
return layoutPlot.value === 'fullwidth'
})
const computedHeaders = computed(() => {
return [...headers.value, ...availableTaxo.value.map(taxo => {
......@@ -64,12 +60,38 @@ const computedHeaders = computed(() => {
}
})]
})
const { result: msResult } = useMeiliSearch('refseq')
const computedWidth = computed(() => {
const currentWidth = fullWidth.value ? width.value : width.value / 2
return Math.max(currentWidth, 550);
});
const allHits = ref([])
onMounted(async () => {
const params = {
facets: ["*"],
filter: [],
sort: ["type:asc"],
limit: 500000
}
await getAllHits({ index: "refseq", params, query: "" })
})
async function getAllHits(params) {
console.log("refresh hits")
console.log(params)
console.log(params.index)
if (params.index === 'refseq') {
console.log(params.index)
const { data, error } = await useAsyncMeiliSearch(params)
console.log(error.value)
console.log(data.value)
allHits.value = data.value
}
}
const plotHeight = computed(() => {
return computedWidth.value / 3;
// return 500
......@@ -87,11 +109,10 @@ const dataTableServerProps = computed(() => {
}
})
const defaultBarPlotOptions = computed(() => {
const y = logTransform.value ? { nice: true, grid: true, type: 'symlog' } : { nice: true, grid: true, type: "linear" }
// const y = { nice: true, grid: true }
return {
x: { label: null, tickRotate: 45, ticks: 10 },
y,
y: { grid: true, type: scaleType.value },
color: { legend: true },
width: computedWidth.value,
height: plotHeight.value + 100,
......@@ -99,11 +120,10 @@ const defaultBarPlotOptions = computed(() => {
})
const computedSystemDistribution = computed(() => {
if (facetStore.facets?.facetDistribution?.type) {
return Object.entries(facetStore.facets.facetDistribution.type).map(([key, value]) => {
if (toValue(msResult)?.facetDistribution?.type) {
return Object.entries(toValue(msResult).facetDistribution.type).map(([key, value]) => {
return {
type: key,
// count: logTransform.value ? Math.log(value) : value
count: value
}
}).sort()
......@@ -129,8 +149,8 @@ const computedDistriSystemOptions = computed(() => {
};
});
const computedTaxonomyDistribution = computed(() => {
if (facetStore.facets?.facetDistribution?.[selectedTaxoRank.value]) {
return Object.entries(facetStore.facets.facetDistribution[selectedTaxoRank.value]).map(([key, value]) => {
if (toValue(msResult)?.facetDistribution?.[selectedTaxoRank.value]) {
return Object.entries(toValue(msResult).facetDistribution[selectedTaxoRank.value]).map(([key, value]) => {
return {
[selectedTaxoRank.value]: key,
count: value
......@@ -172,64 +192,125 @@ function namesToAccessionChips(names: string[]) {
return { ...it, href: new URL(it.title, "http://toto.pasteur.cloud").toString() }
})
}
const taxoPanel: Ref<number> = ref(0)
const systemPanel: Ref<number> = ref(0)
const systemPanel: Ref<number> = ref(["table"])
const layoutPlot: Ref<string[]> = ref("grid")
const binPlotOptions = ref({
marginLeft: 150,
marginBottom: 200,
padding: 0,
width: 1920,
grid: true,
x: { tickRotate: 90, tip: true, },
color: { scheme: "turbo", legend: true },
})
const binPlotDataOptions = computed(() => {
return allHits.value?.hits?.length > 0 ? {
...binPlotOptions.value,
color: {
...binPlotOptions.value.color,
type: scaleType.value
},
// fy: { domain: groupSortDomain.value },
marks: [
Plot.cell(allHits.value?.hits ?? [], Plot.group({ fill: "count" }, { x: "type", y: selectedTaxoRank.value, tip: true, inset: 0.5, sort: { y: "fill" } })),
]
} : null
})
const scaleType = ref("linear")
</script>
<template>
<v-card flat class="mb-2" color="transparent">
<v-toolbar density="compact">
<v-toolbar-title>Distributions</v-toolbar-title>
<v-btn-toggle v-model="distriTool" multiple density="compact" rounded="false" variant="text" color="primary"
<v-toolbar>
<!-- <v-toolbar-title>Plots</v-toolbar-title> -->
<v-btn-toggle v-model="layoutPlot" density="compact" rounded="false" variant="text" color="primary" mandatory
class="mx-2">
<v-btn icon="md:fullscreen" value="fullwidth"></v-btn>
<v-btn icon="mdi-math-log" value="log"></v-btn>
<v-btn icon="md:grid_view" value="grid"></v-btn>
<v-btn icon="md:view_agenda" value="fullwidth"></v-btn>
</v-btn-toggle>
<v-spacer></v-spacer>
<v-select v-model="selectedTaxoRank" :items="availableTaxo" density="compact" label="Select taxonomic rank"
hide-details="auto" class="mx-2"></v-select>
<!-- <v-btn-toggle v-model="scaleTransform" density="compact" mandatory rounded="false" variant="text"
color="primary" class="mx-2">
<v-btn icon="mdi-math-log" value="linear">linear</v-btn>
<v-btn value="pow">pow</v-btn>
<v-btn icon="mdi-math-log" value="sqrt">sqrt</v-btn>
<v-btn icon="mdi-math-log" value="symlog">symlog</v-btn>
<v-btn icon="mdi-math-log" value="log">log</v-btn>
</v-btn-toggle> -->
<v-select v-model="scaleType" class="mx-2" density="compact" :items="['linear', 'sqrt', 'symlog']"
label="Scale Type" hide-details="auto"></v-select>
</v-toolbar>
<v-row align="start" class="my-2">
<v-col :cols="fullWidth ? 12 : 6">
<v-card color="transparent" flat>
<v-expansion-panels v-model="systemPanel">
<v-expansion-panel elevation="3">
<v-expansion-panel-title color="grey-lighten-4">Systems</v-expansion-panel-title>
<v-expansion-panel-text>
<PlotFigure :options="unref(computedDistriSystemOptions)" defer></PlotFigure>
</v-expansion-panel-text>
</v-expansion-panel>
</v-expansion-panels>
</v-card>
</v-col>
<v-col :cols="fullWidth ? 12 : 6">
<v-card flat color="transparent">
<v-expansion-panels v-model="taxoPanel">
<v-expansion-panel elevation="3" :value="true">
<v-expansion-panel-title color="grey-lighten-4">
Taxonomic
</v-expansion-panel-title>
<v-expansion-panel-text>
<v-select v-model="selectedTaxoRank" :items="availableTaxo" density="compact"
label="Select taxonomic rank"></v-select>
<PlotFigure defer :options="unref(computedDistriTaxoOptions)"></PlotFigure>
</v-expansion-panel-text>
</v-expansion-panel>
</v-expansion-panels>
</v-card>
</v-col>
</v-row>
<v-card color="transparent" flat>
<v-expansion-panels v-model="systemPanel" class="my-2" density="compact" multiple>
<v-expansion-panel elevation="3" value="barplot">
<v-expansion-panel-title color="grey-lighten-4"><v-icon color="primary"
class="mr-2">mdi-chart-bar</v-icon>Systems - Taxonomic</v-expansion-panel-title>
<v-expansion-panel-text>
<v-card flat color="transparent">
<v-row align="start">
<v-col :cols="fullWidth ? 12 : 6">
<PlotFigure :options="unref(computedDistriSystemOptions)" defer></PlotFigure>
</v-col>
<v-col :cols="fullWidth ? 12 : 6">
<PlotFigure defer :options="unref(computedDistriTaxoOptions)"></PlotFigure>
</v-col>
</v-row>
</v-card>
</v-expansion-panel-text>
</v-expansion-panel>
<v-expansion-panel elevation="3" value="matrix">
<v-expansion-panel-title color="grey-lighten-4"><v-icon color="primary"
class="mr-2">mdi-data-matrix</v-icon>Heatmap</v-expansion-panel-title>
<v-expansion-panel-text>
<v-card flat color="transparent">
<PlotFigure v-if="toValue(binPlotDataOptions) !== null" :options="unref(binPlotDataOptions)"
defer>
</PlotFigure>
</v-card>
</v-expansion-panel-text>
</v-expansion-panel>
<v-expansion-panel elevation="3" value="table">
<v-expansion-panel-title color="grey-lighten-4"><v-icon color="primary"
class="mr-2">mdi-table</v-icon>Table</v-expansion-panel-title>
<v-expansion-panel-text>
<ServerDbTable title="RefSeq" db="refseq" :sortBy="sortBy" :facets="facets"
:data-table-server-props="dataTableServerProps" @refresh:search="getAllHits">
<template #top>
<v-toolbar><v-toolbar-title class="text-capitalize">
RefSeq
</v-toolbar-title><v-spacer></v-spacer>
</v-toolbar>
</template>
<template #[`item.accession_in_sys`]="{ item }">
<CollapsibleChips :items="namesToAccessionChips(item.accession_in_sys)">
</CollapsibleChips>
</template>
</ServerDbTable>
</v-expansion-panel-text>
</v-expansion-panel>
</v-expansion-panels>
</v-card>
</v-card>
<ServerDbTable title="RefSeq" db="refseq" :sortBy="sortBy" :facets="facets"
:data-table-server-props="dataTableServerProps">
<template #[`item.accession_in_sys`]="{ item }">
<CollapsibleChips :items="namesToAccessionChips(item.accession_in_sys)"></CollapsibleChips>
</template>
</ServerDbTable>
</template>
\ No newline at end of file
<script setup lang="ts">
import * as Plot from "@observablehq/plot";
import PlotFigure from "~/components/PlotFigure";
import type { SortItem } from "@/components/ServerDbTable.vue"
import { ServerDbTable } from "#components"
const sortBy: Ref<SortItem[]> = ref([{ key: 'system', order: "asc" }])
const itemValue = ref("id");
const facets: Ref<string[]> = ref(["system", "completed"])
const headers: Ref<Object[]> = ref([
{ title: "System", key: "system" },
{ title: 'Structure', key: 'structure', sortable: false, removable: false },
{ title: "System", 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 },
{ title: "System genes", key: "system_genes", sortable: false },
{ title: "Sys id", key: "nb_sys" },
{ title: "Completed", key: "completed" },
{ title: "Prediction type", key: "prediction_type" },
{ title: "Num of genes", key: "system_number_of_genes" },
{ title: "pLDDT", key: "plddts" },
{ title: "iptm+ptm", key: "iptm+ptm" },
{ title: "pDockQ", key: "pDockQ" },
{ title: "Type", key: "type" }
{ 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 defaultDataTableServerProps = ref({
showExpand: true
showExpand: false
})
const dataTableServerProps = computed(() => {
......@@ -33,6 +38,9 @@ const dataTableServerProps = computed(() => {
}
})
function namesToCollapsibleChips(names: string[], file: string | null = null) {
if (file === null) {
return names.filter((it) => it !== "").map(it => ({ title: it.split("__").pop() }))
......@@ -51,10 +59,31 @@ function toSystemName(rawName: string) {
return rawName.split(/_|-0/)[0].toLocaleLowerCase()
}
const plddtDistribution = computed(() => {
if (toValue(msResult)?.facetDistribution?.plddts) {
return Object.entries(toValue(msResult).facetDistribution.plddts).map(([key, value]) => { })
}
})
function remove(key) {
headers.value = headers.value.filter(header => header.key !== key)
}
</script>
<template>
<ServerDbTable title="Predicted Structures" db="structure" :sortBy="sortBy" :facets="facets"
:data-table-server-props="dataTableServerProps">
<template #top>
<v-toolbar><v-toolbar-title class="text-capitalize">
Predicted Structures
</v-toolbar-title><v-spacer></v-spacer>
</v-toolbar>
</template>
<template #[`item.proteins_in_the_prediction`]="{ item }">
<CollapsibleChips :items="namesToCollapsibleChips(item.proteins_in_the_prediction, item.fasta_file)">
</CollapsibleChips>
......@@ -62,17 +91,13 @@ function toSystemName(rawName: string) {
<template #[`item.system_genes`]="{ item }">
<CollapsibleChips :items="namesToCollapsibleChips(item.system_genes)"></CollapsibleChips>
</template>
<template #expanded-row="{ columns, item }">
<tr>
<td :colspan="columns.length">
<v-card flat color="transparent">
<v-card-text>
<MolstarPdbePlugin :data-urls="[`/${toSystemName(item.system)}/${pdbNameToCif(item.pdb)}`]">
</MolstarPdbePlugin>
</v-card-text>
</v-card>
</td>
</tr>
<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>
......
......@@ -18,21 +18,22 @@ relevantAbstracts:
## Introduction
Bacteriophages, or phages for short, are viruses that infect bacteria and hijack bacterial cellular machinery to reproduce themselves. Phages are extremely abundant entities, and could be responsible for up to 20-40% of bacterial mortality daily :ref{doi=10.1038/s41586-019-1894-8}. Therefore, phage infection constitutes a very strong evolutionary pressure for bacteria.
Bacteria and their phages have co-existed for billions of years. The pressure of phage infection is thought to be a major driver of bacterial evolution and has favored the development of a diversity of anti-phage weapons. These weapons, namely anti-phage defense systems can be defined as single genes or groups of genes that partially or fully inhibit phage infection. For reviews on anti-phage systems, see : :ref{doi=10.1038/s41586-019-1894-8,10.1146/annurev-micro-020722-013730,10.1016/j.mib.2005.06.006,10.1038/s41579-023-00934-x}.
In response to this evolutionary pressure, bacteria have developed an arsenal of anti-phage defense systems. The term "defense system" here designates either a single gene or a set of genes, which expression provides the bacteria with some level of resistance against phage infection.
## A brief history of anti-phage systems
## History
The first discovered anti-phage system, a Restriction-Modification (RM) system, was described in the early 1950s :ref{doi=10.1128/jb.64.4.557-569.1952,10.1128/jb.65.2.113-121.1953}. In the following decades, a handful of other systems were discovered :ref{doi=10.1016/j.mib.2005.06.006}. In 2007, CRISPR-Cas systems were discovered to be anti-phage systems :ref{doi=10.1126/science.1138140}. As CRISPR-Cas systems and RM systems are extremely prevalent in bacteria, it was thought for some years that the antiviral immune system of bacteria had been mostly elucidated.
The first anti-phage defense system was discovered in the early 1950s by two separate teams of researchers :ref{doi=10.1128/jb.64.4.557-569.1952}, :ref{doi=10.1128/jb.65.2.113-121.1953}. Luria and Human reported a mysterious phenomenon, where one phage was only capable of infecting a specific bacterial strain once. The progeny phages produced by this first round of infection had lost their ability to infect the same strain again, yet remained able to infect other bacterial strains. For them, this could only mean that "the genotype of the host in which a virus reproduces affects the phenotype of the new virus" :ref{doi=10.1128/jb.64.4.557-569.1952}. A similar phenomenon was shortly after described by Bertani and Wiegle.
Following these two major breakthroughs, knowledge of anti-phage systems remained scarce for some years. Yet, in 2011, it was revealed that anti-phage systems tend to colocalize on the bacterial genome in defense-islands :ref{doi=10.1128/JB.05535-11}. This led to a guilt-by-association hypothesis: if a gene or a set of genes is frequently found in bacterial genomes in close proximity to known defense systems, such as RM or CRISPR-Cas systems, then it might constitute a new defense system. This hypothesis was tested systematically in a landarmark study in 2018 :ref{doi=10.1126/science.aar4120} leading to the discovery of 10 novel anti-phage systems. This started the uncovering of an impressive diversity of defense systems in a very short amount of time :ref{doi=10.1038/s41579-023-00934-x}.
Their work was in fact the first report of what would later be named Restriction-Modification ([RM](/defense-systems/rm)) system, which is considered to be the first anti-phage defense system discovered.
To date over 150 types of defense systems have been described, unveiling an unsuspected diversity of molecular mechanisms. The antiviral immune systems of bacteria therefore appear much more complex than previously envisioned, and new discoveries do not seem to be slowing down.
The sighting of a second defense system occured more than 40 years later, in the late 1980s, when several teams around the world observed arrays containing short, palindromic DNA repeats clustered together on the bacterial genome :ref{doi=10.1038/nmicrobiol.2017.92}. Yet, the biological function of these repeats was only elucidated in 2007, when a team of researchers demonstrated that these repeats were part of a new anti-phage defense systems :ref{doi=10.1126/science.1138140}, known as [CRISPR-Cas system](https://en.wikipedia.org/wiki/CRISPR).
## Introducing the defense finder wiki
Following these two major breakthroughs, knowledge of anti-phage systems remained scarce for some years. Yet, in 2011, it was revealed that anti-phage systems tend to colocalize on the bacterial genome in defense-islands :ref{doi=10.1128/JB.05535-11}. This led to a guilt-by-association hypothesis: if a gene or a set of genes is frequently found in bacterial genomes in close proximity to known defense systems, such as RM or CRISPR-Cas systems, then it might constitute a new defense system. This hypothesis was tested systematically in a landarmark study in 2018 :ref{doi=10.1126/science.aar4120} leading to the discovery of 10 novel anti-phage systems. This started the uncovering of an impressive diversity of defense systems in a very short amount of time :ref{10.1038/s41579-023-00934-x }.
The fast pace of discoveries in the field can be intimidating to newcomers and can make it difficult for all to keep track of new discoveries. For this reason, we decided to implement a collaborative knowledge base for the community. This wiki is divided in two sections:
1. A “general concepts” section, introducing key notions and ideas to understand anti-phage defense
2. A section introducing succinctly each of the defense systems currently known.
## List of known defense systems
This wiki is only a first version, and is intended to evolve based on the ideas and needs of the people using it. Whether it is to suggest new pages or to edit existing ones, all contributions are more than welcomed: please do not hesitate to contact us to participate!
To date, more than 150 anti-phage defense systems have been described. An exhaustive list of the systems with experimentally validated anti-phage activity can be found [here](/defense-systems).
......@@ -9,12 +9,24 @@ tableColumns:
Sensor: Unknown
Activator: Unknown
Effector: Unknown
contributors:
- Nathalie Bechon
relevantAbstracts:
- doi: 10.1023/A:1002027321171
- doi: 10.1016/j.mib.2005.06.006
- doi: 10.1128/aem.57.12.3547-3551.1991
- doi: 10.1046/j.1365-2958.1996.371896.x
---
# AbiB
## Description
AbiB is a single-protein abortive infection defense system from *Lactococcus* that degrades mRNA.
## Molecular mechanism
AbiB system is still poorly understood. It is a single-protein system that was described as an abortive infection system. Upon phage infection, AbiB activation leads to a strong degradation of mRNAs :ref{doi=10.1046/j.1365-2958.1996.371896.x} that is expected to be the mechanism of phage inhibition. AbiB expression is constitutive and does increase during phage infection. It is only activated during phage infection, most likely through the recognition of an early phage protein. Which protein, and whether this activation is direct or indirect remains to be elucidated.
## Example of genomic structure
The AbiB system is composed of one protein: AbiB.
Here is an example found in the RefSeq database:
......
......@@ -3,16 +3,29 @@ title: AbiU
layout: article
tableColumns:
article:
doi: 10.1016/j.mib.2005.06.006
doi: 10.1128/AEM.67.11.5225-5232.2001
abstract: |
Abortive infection (Abi) systems, also called phage exclusion, block phage multiplication and cause premature bacterial cell death upon phage infection. This decreases the number of progeny particles and limits their spread to other cells allowing the bacterial population to survive. Twenty Abi systems have been isolated in Lactococcus lactis, a bacterium used in cheese-making fermentation processes, where phage attacks are of economical importance. Recent insights in their expression and mode of action indicate that, behind diverse phenotypic and molecular effects, lactococcal Abis share common traits with the well-studied Escherichia coli systems Lit and Prr. Abis are widespread in bacteria, and recent analysis indicates that Abis might have additional roles other than conferring phage resistance.
This study reports on the identification and characterization of a novel abortive infection system, AbiU, from Lactococcus lactis. AbiU confers resistance to phages from the three main industrially relevant lactococcal phage species: c2, 936, and P335. The presence of AbiU reduced the efficiency of plaquing against specific phage from each species as follows: 3.7 × 10−1, 1.0 × 10−2, and 1.0 × 10−1, respectively. abiU involves two open reading frames,abiU1 (1,772 bp) and abiU2 (1,019 bp). Evidence indicates that AbiU1 is responsible for phage resistance and that AbiU2 may downregulate phage resistance against 936 and P335 type phages but not c2 type phage. AbiU appeared to delay transcription of both phage 712 and c2, with the effect being more marked on phage c2.
Sensor: Unknown
Activator: Unknown
Effector: Unknown
PFAM: PF10592
contributors:
- Nathalie Bechon
relevantAbstracts:
- doi: 10.1023/A:1002027321171
- doi: 10.1016/j.mib.2005.06.006
- doi: 10.1128/AEM.67.11.5225-5232.2001
---
# AbiU
## Description
AbiU is a single-protein abortive infection defense system described in *Lactococcus*.
## Molecular mechanism
The molecular mechanism of AbiU is not well understood. It was shown that cells expressing AbiU showed delayed transcription of phage DNA, although how it is achieved, or how does it protect the bacterial culture is not understood. AbiU was shown to be encoded near another gene that seems to be an inhibitor of defense :ref{doi=10.1128/AEM.67.11.5225-5232.2001}.
## Example of genomic structure
The AbiU system is composed of one protein: AbiU.
......@@ -70,14 +83,3 @@ end
style Title3 fill:none,stroke:none,stroke-width:none
style Title4 fill:none,stroke:none,stroke-width:none
</mermaid>
## Relevant abstracts
::relevant-abstracts
---
items:
- doi: 10.1023/A:1002027321171
- doi: 10.1016/j.mib.2005.06.006
---
::
......@@ -10,6 +10,8 @@ tableColumns:
Activator: Unknown
Effector: Unknown
PFAM: PF00069, PF00176, PF00270, PF00271, PF01507, PF01555, PF02384, PF04851, PF07669, PF07714, PF08378, PF08665, PF08747, PF08849, PF10923, PF13337, PF16565
contributors:
- Marian Dominguez-Mirazo
relevantAbstracts:
- doi: 10.1093/nar/gkaa290
- doi: 10.1093/nar/gky1125
......@@ -20,30 +22,30 @@ relevantAbstracts:
## Description
BREX (for Bacteriophage Exclusion) is a family of anti-phage defense systems. BREX systems are active against both lytic and lysogenic phages. They allow phage adsorption but block phage DNA replication, and are considered to be [RM](/defense-systems/rm)-like systems (1,2). BREX systems are found in around 10% of sequenced microbial genomes (1).
BREX (for Bacteriophage Exclusion) is a family of anti-phage defense systems. BREX systems are active against both lytic and lysogenic phages. They allow phage adsorption but block phage DNA replication, and are considered to be [RM](/defense-systems/rm)-like systems :ref{doi=10.15252/embj.201489455,10.1093/nar/gkaa290}. BREX systems are found in around 10% of sequenced microbial genomes :ref{doi=10.15252/embj.201489455}.
BREX systems can be divided into six subtypes, and are encoded by 4 to 8 genes, some of these genes being mandatory while others are subtype-specific (1).
BREX systems can be divided into six subtypes, and are encoded by 4 to 8 genes, some of these genes being mandatory while others are subtype-specific :ref{doi=10.15252/embj.201489455}.
## Molecular mechanism
*B. cereus* BREX Type 1 system was reported to methylate target motifs in the bacterial genome (1). The methylation activity of this system has been hypothesized to allow for self from non-self discrimination, as it is the case for Restriction-Modification ([RM)](/defense-systems/rm) systems.
*B. cereus* BREX Type 1 system was reported to methylate target motifs in the bacterial genome :ref{doi=10.15252/embj.201489455}. The methylation activity of this system has been hypothesized to allow for self from non-self discrimination, as it is the case for Restriction-Modification ([RM)](/defense-systems/rm) systems.
However, the mechanism through which BREX Type 1 systems defend against phages is distinct from RM systems, and does not seem to degrade phage nucleic acids (1).
However, the mechanism through which BREX Type 1 systems defend against phages is distinct from RM systems, and does not seem to degrade phage nucleic acids :ref{doi=10.15252/embj.201489455}.
To date, BREX molecular mechanism remains to be described.
## Example of genomic structure
The BREX system have been describe in a total of 6 subsystems.
There are 6 subsystems described for the BREX system.
BREX systems necessarily include the pglZ gene (encoding for a putative alkaline phosphatase), which is accompanied by either brxC or pglY. These two genes share only a distant homology but have been hypothesized to fulfill the same function among the different BREX subtypes (1).
BREX systems necessarily include the pglZ gene (encoding for a putative alkaline phosphatase), which is accompanied by either brxC or pglY. These two genes share only a distant homology but have been hypothesized to fulfill the same function among the different BREX subtypes :ref{doi=10.15252/embj.201489455}.
Goldfarb and colleagues reported a 6-gene cassette from *Bacillus cereus* as being the model for BREX Type 1. BREX Type 1 are the most widespread BREX systems, and present two core genes (pglZ and brxC). Four other genes are associated with BREX Type 1 : *pglX (*encoding for a putative methyltransferase), *brxA (*encoding an RNA-binding anti-termination protein)*, brxB (*unknown functio*n), brxC (*encoding for a protein with ATP-binding domain) and *brxL* (encoding for a putative protease) (1,2).
Goldfarb and colleagues reported a 6-gene cassette from *Bacillus cereus* as being the model for BREX Type 1. BREX Type 1 are the most widespread BREX systems, and present two core genes (pglZ and brxC). Four other genes are associated with BREX Type 1 : *pglX (*encoding for a putative methyltransferase), *brxA (*encoding an RNA-binding anti-termination protein)*, brxB (*unknown functio*n), brxC (*encoding for a protein with ATP-binding domain) and *brxL* (encoding for a putative protease) :ref{doi=10.15252/embj.201489455,10.1093/nar/gkaa290}.
Type 2 BREX systems include the system formerly known as Pgl , which is comprised of four genes (pglW, X, Y, and Z) (3), to which Goldfarb and colleagues found often associated two additional genes (brxD, and brxHI).
Type 2 BREX systems include the system formerly known as Pgl, which is comprised of four genes (pglW, X, Y, and Z) :ref{doi=10.1093/nar/gky1125}, to which :ref{doi=10.15252/embj.201489455} found often associated two additional genes (brxD, and brxHI).
Although 4 additional BREX subtypes have been proposed, BREX Type 1 and Type 2 remain the only ones to be experimentally validated. A detailed description of the other subtypes can be found in Goldfarb *et al*., 2015.
Although 4 additional BREX subtypes have been proposed, BREX Type 1 and Type 2 remain the only ones to be experimentally validated. A detailed description of the other subtypes can be found in :ref{doi=10.15252/embj.201489455}.
Here is some example found in the RefSeq database:
......
......@@ -24,7 +24,7 @@ relevantAbstracts:
## Description
Gabija is named after the Lithuanian spirit of fire, protector of home and family. It is a two gene defense system found in 8.5% of the 4360 bacterial and archeal genomes that were initially analyzed :ref{doi=10.1126/science.aar4120}. Both proteins are necessary for defense and are forming a heteromeric octamer complex: GajA forms a central tetramer surrounded by two GajB dimers ref:{doi=10.1101/2023.05.01.538945,10.1093/nar/gkad951}. A phage protein inhibiting Gabija function was described, Gabidja anti defense 1 (Gad1) :ref{doi=10.1101/2023.05.01.538945,10.1101/2023.05.01.538930}.
Gabija is named after the Lithuanian spirit of fire, protector of home and family. It is a two gene defense system found in 8.5% of the 4360 bacterial and archeal genomes that were initially analyzed :ref{doi=10.1126/science.aar4120}. Both proteins are necessary for defense and are forming a heteromeric octamer complex: GajA forms a central tetramer surrounded by two GajB dimers :ref{doi=10.1101/2023.05.01.538945,10.1093/nar/gkad951}. A phage protein inhibiting Gabija function was described, Gabidja anti defense 1 (Gad1) :ref{doi=10.1101/2023.05.01.538945,10.1101/2023.05.01.538930}.
## Molecular mechanism
......
......@@ -10,9 +10,21 @@ tableColumns:
Activator: Unknown
Effector: Unknown
PFAM: PF00069, PF07714, PF08378, PF13086, PF13087, PF13091, PF13245, PF13604
contributors:
- Marian Dominguez-Mirazo
relevantAbstract:
- doi: 10.1016/j.chom.2022.09.017
- doi: 10.1101/2022.12.12.520048
---
# Mokosh
## Description
The Mokosh system was discovered in *E. coli* by examining clusters of genes enrinched in defense islands :ref{doi=10.1016/j.chom.2022.09.017}. It contains genes with an RNA helicase domain and a predicted phospholipase D domain (PLD) nuclease domain. Mutations in the ATP-binding domain of the helicase, and in the active site of the PLD nuclease disrupt phage defense. The system is divided in two types. Mokosh type I has two genes, one gene containing the RNA helicase domain and an additional serine-threonine kinase domain (STK), and one gene containing the PLD nuclease. Type II Mokosh is formed of a single gene containing both the helicase and nuclease domains. Recent efforts have shown homology between the Mokosh system and human proteins involved in the piRNA pathway, a defense mechanism of animal germlines that prevents expression of transposable elements :ref{doi=10.1101/2022.12.12.520048}. The system gets its name from the goddess protector of women's destiny in Slavic mythology :ref{doi=10.1016/j.chom.2022.09.017}.
## Molecular mechanisms
As far as we are aware, the molecular mechanism is unknown.
## Example of genomic structure
The Mokosh system have been describe in a total of 2 subsystems.
......@@ -126,13 +138,5 @@ end
style Title3 fill:none,stroke:none,stroke-width:none
style Title4 fill:none,stroke:none,stroke-width:none
</mermaid>
## Relevant abstracts
::relevant-abstracts
---
items:
- doi: 10.1016/j.chom.2022.09.017
---
::
......@@ -20,7 +20,7 @@ relevantAbstracts:
Phage-inducible chromosomal island-like elements (PLEs) are chromosomally-integrated phage parasites described in *Vibrio cholerae* :ref{doi=10.7554/eLife.53200}. PLEs excise in response to infection by phage ICP1 and halt its progeny production. PLE halts ICP1 infection by means of redirecting virion packaging and interfiring with ICP1 genome replication :ref{doi=10.1093/nar/gkz1005}. NixI is a PLE-encoded nuclease that nicks the ICP1 genome at specific sites preventing transition to the rolling circle replication (RCR) :ref{doi=10.1093/nar/gkac002}.
## Molecular mechanisms
The NixI endonuclease cleaves the ICP1 genome at the GNAANCTT motif :ref{doi=10.1093/nar/gkac002}. It creates nicks and does not cause double stranded breaks ref:{doi=10.1093/nar/gkac002}.
The NixI endonuclease cleaves the ICP1 genome at the GNAANCTT motif :ref{doi=10.1093/nar/gkac002}. It creates nicks and does not cause double stranded breaks :ref{doi=10.1093/nar/gkac002}.
## Example of genomic structure
......
......@@ -8,11 +8,23 @@ tableColumns:
The Old protein of bacteriophage P2 is responsible for interference with the growth of phage lambda and for killing of recBC mutant Escherichia coli. We have purified Old fused to the maltose-binding protein to 95% purity and characterized its enzymatic properties. The Old protein fused to maltose-binding protein has exonuclease activity on double-stranded DNA as well as nuclease activity on single-stranded DNA and RNA. The direction of digestion of double-stranded DNA is from 5' to 3', and digestion initiates at either the 5'-phosphoryl or 5'-hydroxyl terminus. The nuclease is active on nicked circular DNA, degrades DNA in a processive manner, and releases 5'-phosphoryl mononucleotides.
Sensor: Unknown
Activator: Unknown
Effector: Unknown
Effector: Nucleic acid degrading
PFAM: PF13175, PF13304
contributors:
- Marian Dominguez-Mirazo
relevantAbstracts:
- doi: 10.1128/jb.177.3.497-501.1995
- doi: 10.1128/jb.177.3.497-501.1995
---
# Old_exonuclease
## Description
The OLD proteins are a family of nucleases present in bacteria, archaea, and viruses :ref{doi=10.1093/nar/gkz703}. The OLD protein found in the P2 *E.coli* prophage is the best characterized one. The protein is an exonuclease that digests dsDNA in the 5' to 3' direction :ref{doi=10.1128/jb.177.3.497-501.1995}. It also has nuclease activity against single stranded DNA and RNA :ref{doi=10.1128/jb.177.3.497-501.1995}. It's been shown to protect against phage lambda :ref{doi=10.1128/jb.177.3.497-501.1995}, and when cloned with the P2 Tin accesory gene, it was shown to protect against other *E. coli* phages :ref{doi=10.1016/j.chom.2022.02.018}. The protein also contains an ATPase domain that affects nuclease activity :ref{doi=10.1128/jb.177.3.497-501.1995}. Inhibition of the RecBCD complex activates the OLD nuclease :ref{doi=10.1016/j.mib.2023.102325}. OLD proteins are divided into two classes based on amino acid sequence conservation and gene neighborhood :ref{doi=10.1093/nar/gkz703}. The P2 associated protein belongs to class 2 :ref{doi=10.1093/nar/gkz703}.
## Molecular Mechanisms
The old_exonuclease is dsDNA exonuclease that digest in the 5' to 3' direction :ref{doi=10.1128/jb.177.3.497-501.1995}. To our knowledge, other aspects of the molecular mechanisms remain unknown.
## Example of genomic structure
The Old_exonuclease system is composed of one protein: Old_exonuclease.
......@@ -71,9 +83,3 @@ end
style Title3 fill:none,stroke:none,stroke-width:none
style Title4 fill:none,stroke:none,stroke-width:none
</mermaid>
## Relevant abstracts
**Rousset, F. et al. Phages and their satellites encode hotspots of antiviral systems. Cell Host & Microbe 30, 740-753.e5 (2022).**
Bacteria carry diverse genetic systems to defend against viral infection, some of which are found within prophages where they inhibit competing viruses. Phage satellites pose additional pressures on phages by hijacking key viral elements to their own benefit. Here, we show that E. coli P2-like phages and their parasitic P4-like satellites carry hotspots of genetic variation containing reservoirs of anti-phage systems. We validate the activity of diverse systems and describe PARIS, an abortive infection system triggered by a phage-encoded anti-restriction protein. Antiviral hotspots participate in inter-viral competition and shape dynamics between the bacterial host, P2-like phages, and P4-like satellites. Notably, the anti-phage activity of satellites can benefit the helper phage during competition with virulent phages, turning a parasitic relationship into a mutualistic one. Anti-phage hotspots are present across distant species and constitute a substantial source of systems that participate in the competition between mobile genetic elements.
......@@ -10,9 +10,19 @@ tableColumns:
Activator: Unknown
Effector: Unknown
PFAM: PF02086
contributors:
- Nathalie Bechon
relevantAbstracts:
- doi: 10.1038/s41564-022-01219-4
---
# PD-Lambda-5
##Description
PD-lambda-5 is a two-gene system identified in a P2-like prophage. It encodes a protein with a nuclease and a HEPN domain, and a predicted methyltransferase. It confers broad anti-phage defense and does not seem to mediate abortive infection.
##Molecular mechanism
PD-lambda-5 molecular mechanism has not been described to date. It confers protection against a broad range of phages, and does not seem to be an abortive infection system.
## Example of genomic structure
The PD-Lambda-5 system is composed of 2 proteins: PD-Lambda-5_A and, PD-Lambda-5_B.
......@@ -83,13 +93,3 @@ end
style Title3 fill:none,stroke:none,stroke-width:none
style Title4 fill:none,stroke:none,stroke-width:none
</mermaid>
## Relevant abstracts
::relevant-abstracts
---
items:
- doi: 10.1038/s41564-022-01219-4
---
::
......@@ -10,9 +10,19 @@ tableColumns:
Activator: Unknown
Effector: Unknown
PFAM: PF13175, PF13304
contributors:
- Nathalie Bechon
relevantAbstracts:
- doi: 10.1038/s41564-022-01219-4
---
# PD-T4-4
## Description
PD-T4-4 is a defense system composed of two proteins, a P-loop NTPase and a nuclease, that is most likely protecting the bacterial population through abortive infection. It was identified from an ICE in an *E. coli* genome.
## Molecular mechanisms
PD-T4-4 molecular mechanism is currently unknown, although it is most likely an abortive infection system.
## Example of genomic structure
The PD-T4-4 system is composed of 2 proteins: PD-T4-4_A and, PD-T4-4_B.
......@@ -21,7 +31,7 @@ Here is an example found in the RefSeq database:
![pd-t4-4](/pd-t4-4/PD-T4-4.svg){max-width=750px}
PD-T4-4 system in the genome of *Escherichia coli* (GCF_013376895.1) is composed of 2 proteins: PD-T4-4_B (WP_176670803.1)and, PD-T4-4_A (WP_027920142.1).
PD-T4-4 system in the genome of *Escherichia coli* (GCF_013376895.1) is composed of 2 proteins: PD-T4-4_B (WP_176670803.1) and, PD-T4-4_A (WP_027920142.1).
## Distribution of the system among prokaryotes
......@@ -78,13 +88,4 @@ end
style Title3 fill:none,stroke:none,stroke-width:none
style Title4 fill:none,stroke:none,stroke-width:none
</mermaid>
## Relevant abstracts
::relevant-abstracts
---
items:
- doi: 10.1038/s41564-022-01219-4
---
::
......@@ -5,14 +5,25 @@ tableColumns:
article:
doi: 10.1038/s41564-022-01219-4
abstract: |
The ancient, ongoing coevolutionary battle between bacteria and their viruses, bacteriophages, has given rise to sophisticated immune systems including restriction-modification and CRISPR-Cas. Many additional anti-phage systems have been identified using computational approaches based on genomic co-location within defence islands, but these screens may not be exhaustive. Here we developed an experimental selection scheme agnostic to genomic context to identify defence systems in 71 diverse E. coli strains. Our results unveil 21 conserved defence systems, none of which were previously detected as enriched in defence islands. Additionally, our work indicates that intact prophages and mobile genetic elements are primary reservoirs and distributors of defence systems in E. coli, with defence systems typically carried in specific locations or hotspots. These hotspots encode dozens of additional uncharacterized defence system candidates. Our findings reveal an extended landscape of antiviral immunity in E. coli and provide an approach for mapping defence systems in other species.
The ancient, ongoing coevolutionary battle between bacteria and their viruses, bacteriophages, has given rise to sophisticated immune systems including restriction-modification and CRISPR-Cas. Many additional anti-phage systems have been identified using computational approaches based on genomic co-location within defence islands, but these screens may not be exhaustive. Here we developed an experimental selection scheme agnostic to genomic context to identify defence systems in 71 diverse *E. coli* strains. Our results unveil 21 conserved defence systems, none of which were previously detected as enriched in defence islands. Additionally, our work indicates that intact prophages and mobile genetic elements are primary reservoirs and distributors of defence systems in *E. coli*, with defence systems typically carried in specific locations or hotspots. These hotspots encode dozens of additional uncharacterized defence system candidates. Our findings reveal an extended landscape of antiviral immunity in *E. coli* and provide an approach for mapping defence systems in other species.
Sensor: Unknown
Activator: Unknown
Effector: Unknown
PFAM: PF00069, PF03793, PF07714
contributors:
- Marian Dominguez-Mirazo
relevantAbstracts:
- doi: 10.1038/s41564-022-01219-4
---
# PD-T4-6
## Description
The PD-T4-6 system is composed of a single protein. It was discovered via a selection screening of 71 *E. coli* strains challenged with diverse phage. The name stands from Phage Defense (PD) and the phage with which the strain was challenge (T4) :ref{doi=10.1038/s41564-022-01219-4}. The system has been identified as an Abortive Infection (Abi) system :ref{doi=10.1038/s41564-022-01219-4,10.1016/j.mib.2023.102312}. The protein was found within a P2-like prophage and contains a predicted Der/Thr kinase domain. Site-specific mutation in the domain reduces phage protection :ref{doi=10.1038/s41564-022-01219-4}.
## Molecular mechanisms
As far as we are aware, the molecular mechanism is unknown.
## Example of genomic structure
The PD-T4-6 system is composed of one protein: PD-T4-6.
......@@ -70,13 +81,3 @@ end
style Title3 fill:none,stroke:none,stroke-width:none
style Title4 fill:none,stroke:none,stroke-width:none
</mermaid>
## Relevant abstracts
::relevant-abstracts
---
items:
- doi: 10.1038/s41564-022-01219-4
---
::
......@@ -10,9 +10,25 @@ tableColumns:
Activator: Direct
Effector: Nucleic acid degrading
PFAM: PF00270, PF02384, PF04313, PF04851, PF12008, PF12161, PF13166, PF18766
contributors:
- Ernest Mordret
relevant abstracts:
- doi: 10.1186/1743-422X-7-360
- doi: 10.1006/jmbi.1995.0343
---
# PrrC
## Description
The PrrC system protects bacteria against phages via an abortive infection. It is composed of a single effector protein, but relies on the presence of a full type Ic restriction-modification system in the vicinity. PrrC proteins are therefore typically found embedded in a larger RM system.
## Molecular mechanism
The effector protein prrC complements a RM system by cutting tRNALys in the anticodon loop, upstream of the wobble nucleotide and causes the arrest of phage protein synthesis and phage growth.
prrC serves as a guardian of the acrivity of EcoprrI, which can be inactivated by the Stp peptide of phage T4 at the beginning of infection. Inactivation of EcoprrI by Stp induces a conformation change that in turn activates PrrC, releasing its nuclease activity and stalling host and phage growth :ref{doi=10.1006/jmbi.1995.0343}.
Because it sabotages the host's translation machinery, prrC is considered to be an abortive infection system.
## Example of genomic structure
The PrrC system is composed of 4 proteins: EcoprrI, Type_I_S, PrrC and, Type_I_REases.
......@@ -78,14 +94,3 @@ end
style Title3 fill:none,stroke:none,stroke-width:none
style Title4 fill:none,stroke:none,stroke-width:none
</mermaid>
## Relevant abstracts
::relevant-abstracts
---
items:
- doi: 10.1006/jmbi.1995.0343
- doi: 10.1186/1743-422X-7-360
---
::
---
title: RefSeq DB
layout: db
navigation: true
navigation:
icon: "mdi-database"
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Cras lobortis nulla ac mauris aliquet lacinia.
Praesent viverra turpis orci, eget blandit ligula placerat nec.
Mauris a libero dui. Aenean sit amet quam at enim molestie tristique nec consequat libero.
Vestibulum rutrum tellus nec dui ornare, sit amet euismod velit faucibus. Aenean lectus mauris, convallis non dolor tincidunt, laoreet pulvinar diam. Maecenas at dignissim massa. Curabitur felis felis, maximus vitae mi non, condimentum rutrum urna. Phasellus consectetur libero sit amet iaculis dapibus.
Sed varius eget metus sed congue. Donec ut sodales lectus. Integer auctor maximus quam nec porta. Nulla urna magna, congue in sodales non, blandit eu lorem. Maecenas id massa sit amet libero elementum lobortis ut vel nibh. Integer sed ante eu tellus iaculis porttitor id at ante. Fusce at venenatis ante, et faucibus magna. Integer ut egestas diam. In vel blandit urna. Mauris nec tellus ut orci blandit consectetur. Nulla cursus tellus velit, vitae finibus lacus efficitur ut.
::refseq-db
::
---
title: Structures DB
layout: db
navigation: true
navigation:
icon: "mdi-database"
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras lobortis nulla ac mauris aliquet lacinia. Praesent viverra turpis orci, eget blandit ligula placerat nec. Mauris a libero dui. Aenean sit amet quam at enim molestie tristique nec consequat libero. Vestibulum rutrum tellus nec dui ornare, sit amet euismod velit faucibus. Aenean lectus mauris, convallis non dolor tincidunt, laoreet pulvinar diam. Maecenas at dignissim massa. Curabitur felis felis, maximus vitae mi non, condimentum rutrum urna. Phasellus consectetur libero sit amet iaculis dapibus.
Sed varius eget metus sed congue. Donec ut sodales lectus. Integer auctor maximus quam nec porta. Nulla urna magna, congue in sodales non, blandit eu lorem. Maecenas id massa sit amet libero elementum lobortis ut vel nibh. Integer sed ante eu tellus iaculis porttitor id at ante. Fusce at venenatis ante, et faucibus magna. Integer ut egestas diam. In vel blandit urna. Mauris nec tellus ut orci blandit consectetur. Nulla cursus tellus velit, vitae finibus lacus efficitur ut.
::structure-db
::
\ No newline at end of file
<template>
<LayoutWrapper :fluid="true" :toc="false" :edit="false">
<LayoutWrapper :fluid="true" :toc="false" :edit="true">
<slot />
</LayoutWrapper>
</template>
......