Skip to content

Commit

Permalink
Logo, add exp info to lineage
Browse files Browse the repository at this point in the history
  • Loading branch information
jpfisher72 committed Apr 23, 2024
1 parent 1869475 commit 26b3d2c
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 105 deletions.
Binary file added immuscreen/public/igSCREEN.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
101 changes: 8 additions & 93 deletions immuscreen/src/app/icres/icresbyregion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ import { client } from "../../common/utils"
import { DataTable } from "@weng-lab/psychscreen-ui-components"
import React, { useState } from "react"
import { ApolloError, useQuery } from "@apollo/client"
import { gql } from "@apollo/client"
import { ReadonlyURLSearchParams, useSearchParams, useRouter } from "next/navigation"
import Grid2 from "@mui/material/Unstable_Grid2/Grid2"
import { StyledTab } from "../../common/utils"
import { CircularProgress, Collapse, List, ListItemButton, ListItemIcon, ListItemText, Stack, Tooltip, Typography } from "@mui/material"
import { CircularProgress, Collapse, List, ListItemButton, ListItemText, Stack, Tooltip, Typography } from "@mui/material"
import { Tabs } from "@mui/material"
import { ICRES_ACTIVE_EXPERIMENTS, ICRES_QUERY } from "./queries"
import { experimentInfo } from "../../common/consts"
import { getCellDisplayName } from "../celllineage/utils"
import { ExpandLess, ExpandMore, InfoOutlined, StarBorder } from "@mui/icons-material"
import { CellQueryValue } from "../celllineage/types"
import { ExpandLess, ExpandMore, InfoOutlined } from "@mui/icons-material"
import { ICRE_Data, Experiment_Data } from "./types"
import { ActiveCellTypesList, ActiveExperimentList } from "./utils"

export const IcresByRegion = (props) => {
const searchParams: ReadonlyURLSearchParams = useSearchParams()!
Expand All @@ -23,9 +23,6 @@ export const IcresByRegion = (props) => {
setValue(newValue)
}

type ICRE_Data = { accession: string, rdhs: string, celltypes: CellQueryValue[], coordinates: { chromosome: string, start: number, end: number, } }
type Experiment_Data = { grouping: string, description: string, name: string, start: number, value: number }

const { loading: loading_icres, data: data_icres, error: error_icres }: { loading: boolean, data: { iCREQuery: ICRE_Data[] }, error?: ApolloError } = useQuery(ICRES_QUERY, {
variables: {
coordinates: {
Expand Down Expand Up @@ -125,42 +122,16 @@ export const IcresByRegion = (props) => {
<Typography variant="body2">
Active Cell Types
</Typography>
<Tooltip title="Activity in cell types determined by aggregated ATAC-seq signal z-score of >1.64 (95th percentile)">
<Tooltip arrow title="Activity in cell types determined by aggregated ATAC-seq signal z-score of >1.64 (95th percentile)">
<InfoOutlined />
</Tooltip>
</Stack>
)
},
value: (row) => row.celltypes.map(x => getCellDisplayName(x)).length,
FunctionalRender: (row) => {
const [open, setOpen] = useState(false)

const celltypes = [... new Set(row.celltypes.map(x => getCellDisplayName(x, true)))].sort()

const handleClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
event.stopPropagation()
setOpen(!open);
};

return (
celltypes.length > 0 ?
<List>
<ListItemButton onClick={(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => handleClick(event)}>
<ListItemText primary={"Active in " + celltypes.length + " immune cell types"} />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open} timeout="auto" unmountOnExit>
<List sx={{ pl: 2 }} component="div" disablePadding>
{
celltypes.map((cell: string) =>
<ListItemText key={cell} primary={"\u2022 " + cell} />
)
}
</List>
</Collapse>
</List>
:
<Typography pl={2}>Not Active</Typography>
<ActiveCellTypesList celltypes={row.celltypes} />
)
}
},
Expand All @@ -172,73 +143,17 @@ export const IcresByRegion = (props) => {
<Typography variant="body2">
Active Experiments
</Typography>
<Tooltip title="Activity in individual experiments determined by an ATAC-seq signal z-score of >1.64 (95th percentile)">
<Tooltip arrow title="Activity in individual experiments determined by an ATAC-seq signal z-score of >1.64 (95th percentile)">
<InfoOutlined />
</Tooltip>
</Stack>
)
},
value: (row: ICRE_Row) => row?.activeExps ? Object.values(row.activeExps).flat().length : 0,
FunctionalRender: (row: ICRE_Row) => {
const [open, setOpen] = useState(false)

const handleClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
event.stopPropagation()
setOpen(!open);
};


type GroupListProps = { exps: Experiment_Data[], grouping: string }

const GroupList: React.FC<GroupListProps> = (props: GroupListProps) => {
const [openGroup, setOpenGroup] = useState(false)

const handleClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
event.stopPropagation()
setOpenGroup(!openGroup);
};

return (
<List disablePadding>
<ListItemButton onClick={(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => handleClick(event)}>
<ListItemText primary={`${props.grouping} (${props.exps.length})`} />
{openGroup ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={openGroup} timeout="auto" unmountOnExit>
<List sx={{ pl: 2 }} component="div" disablePadding>
{
props.exps.sort((a, b) => experimentInfo[a.name].order - experimentInfo[b.name].order).map((exp) =>
<Tooltip key={exp.name} title={exp.description}>
<Stack direction={"row"} alignItems={"center"}>
<ListItemText primary={"\u2022 " + exp.name} />
<InfoOutlined fontSize="small" />
</Stack>
</Tooltip>
)
}
</List>
</Collapse>
</List>
)
}

return (
row?.activeExps ?
<List disablePadding>
<ListItemButton onClick={(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => handleClick(event)}>
<ListItemText primary={"Active in " + Object.values(row.activeExps).flat().length + " experiments"} />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open} timeout="auto" unmountOnExit>
<List sx={{ pl: 2 }} component="div" disablePadding>
{
Object.entries(row.activeExps).map(([grouping, exps]: [string, Experiment_Data[]]) =>
<GroupList key={grouping} exps={exps} grouping={grouping} />
)
}
</List>
</Collapse>
</List>
<ActiveExperimentList activeExps={row.activeExps} />
:
<CircularProgress />
)
Expand Down
53 changes: 43 additions & 10 deletions immuscreen/src/app/icres/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { useRouter } from "next/navigation"
import { StyledTab } from "../../common/utils"
import { client } from "../../common/utils"
import SearchIcon from "@mui/icons-material/Search"
import { CircularProgress, Stack, ToggleButtonGroup, Typography } from "@mui/material"
import { Box, CircularProgress, Collapse, List, ListItemButton, ListItemText, Stack, ToggleButtonGroup, Typography } from "@mui/material"
import { Tabs } from "@mui/material"
import Grid2 from "@mui/material/Unstable_Grid2/Grid2"
import { TextField, IconButton, InputAdornment } from "@mui/material"
import { FormControl, MenuItem } from "@mui/material"
import { useQuery } from "@apollo/client"
import { ApolloError, useQuery } from "@apollo/client"

import Select, { SelectChangeEvent } from "@mui/material/Select";
import { ReadonlyURLSearchParams, useSearchParams} from "next/navigation"
Expand All @@ -18,18 +18,21 @@ import { CcreAutoComplete } from "../../common/components/mainsearch/CcreAutocom
import { DataTable } from "@weng-lab/psychscreen-ui-components"

import {IcresByRegion} from "./icresbyregion"
import { ATAC_UMAP_QUERY, EBI_ASSO_QUERY, ICRES_BYCT_ZSCORES_QUERY, ICRES_CT_ZSCORES_QUERY, ICRES_QUERY } from "./queries"
import { ATAC_UMAP_QUERY, EBI_ASSO_QUERY, ICRES_ACTIVE_EXPERIMENTS, ICRES_BYCT_ZSCORES_QUERY, ICRES_CT_ZSCORES_QUERY, ICRES_QUERY } from "./queries"
import InputLabel from "@mui/material/InputLabel";
import { stringToColour } from "../../common/utils";
import { AtacBarPlot } from "./atacbarplot"
import { cellTypeStaticInfo } from "../../common./../common/consts";
import { UmapPlot } from "../../common/components/umapplot";
import CellTypeTree from "../../common/components/cellTypeTree"
import { generateCellLineageTreeState, getCellColor } from "../celllineage/utils"
import { generateCellLineageTreeState, getCellColor, getCellDisplayName } from "../celllineage/utils"


//Need better text styling
import ToggleButton from '@mui/material/ToggleButton';
import { Experiment_Data } from "./types"
import { ExpandLess, ExpandMore } from "@mui/icons-material"
import { ActiveCellTypesList, ActiveExperimentList } from "./utils"


export default function Icres() {
Expand Down Expand Up @@ -73,8 +76,7 @@ export default function Icres() {
client,
})


const { loading: aloading, data: adata } = useQuery(ICRES_QUERY, {
const { loading: aloading, data: adata, error: error_adata } = useQuery(ICRES_QUERY, {
variables: {
accession: searchParams.get('accession')
},
Expand All @@ -84,6 +86,29 @@ export default function Icres() {
client,
})

const { loading: loading_experiments, data: data_experiments, error: error_experiments }: { loading: boolean, data: { calderoncorcesAtacQuery: Experiment_Data[] }, error?: ApolloError } = useQuery(ICRES_ACTIVE_EXPERIMENTS, {
variables: {
accession: searchParams.get('accession') ? [searchParams.get('accession')] : []
},
skip: !searchParams.get('accession'),
fetchPolicy: "cache-and-network",
nextFetchPolicy: "cache-first",
client,
})

//Parse experiment info
let activeExps: { [key: string]: Experiment_Data[] } = {}
data_experiments?.calderoncorcesAtacQuery.forEach(exp => {
//Cutoff for experiment activity set at 1.64
if (exp.value > 1.64) {
if (activeExps[exp.grouping]) {
activeExps[exp.grouping] = [...activeExps[exp.grouping], exp]
} else {
activeExps[exp.grouping] = [exp]
}
}
});


let barplotdata = icrezscoredata && icrezscoredata.calderoncorcesAtacQuery.map(ic => {
return {
Expand Down Expand Up @@ -376,11 +401,19 @@ return !searchParams.get('accession') && !searchParams.get('chromosome') ? (
(aloading ?
<CircularProgress />
:
(adata?.iCREQuery[0].celltypes.length === 0) ?
<Typography>Not identified as active in immune cells</Typography>
:
<Stack rowGap={2}>
<Typography>{searchParams.get('accession')} is determined to be active in the following cells:</Typography>
<Stack direction={"row"}>
{
aloading ? <CircularProgress />
: error_adata ? <Typography>Something went wrong fetching activity in cell types</Typography>
: <Box maxWidth={500}><ActiveCellTypesList celltypes={adata?.iCREQuery[0].celltypes} /></Box>
}
{
loading_experiments ? <CircularProgress />
: error_experiments ? <Typography>Something went wrong fetching activity in individual experiments</Typography>
: <Box maxWidth={500}><ActiveExperimentList activeExps={activeExps} /></Box>
}
</Stack>
<CellTypeTree
width={830}
height={1100}
Expand Down
5 changes: 5 additions & 0 deletions immuscreen/src/app/icres/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { CellQueryValue } from "../celllineage/types"


export type ICRE_Data = { accession: string, rdhs: string, celltypes: CellQueryValue[], coordinates: { chromosome: string, start: number, end: number, } }
export type Experiment_Data = { grouping: string, description: string, name: string, start: number, value: number }
101 changes: 101 additions & 0 deletions immuscreen/src/app/icres/utils.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { useState } from "react";
import { Experiment_Data } from "./types";
import { ExpandLess, ExpandMore, InfoOutlined } from "@mui/icons-material";
import { List, ListItemButton, ListItemText, Collapse, Tooltip, Stack } from "@mui/material";
import { experimentInfo } from "../../common/consts";
import { CellQueryValue } from "../celllineage/types";
import { getCellDisplayName } from "../celllineage/utils";

type GroupListProps = { exps: Experiment_Data[], grouping: string }

const ExperimentGroupList: React.FC<GroupListProps> = (props: GroupListProps) => {
const [openGroup, setOpenGroup] = useState(false)

const handleClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
event.stopPropagation()
setOpenGroup(!openGroup);
};

return (
<List disablePadding>
<ListItemButton onClick={(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => handleClick(event)}>
<ListItemText primary={`${props.grouping} (${props.exps.length})`} />
{openGroup ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={openGroup} timeout="auto" unmountOnExit>
<List sx={{ pl: 2 }} component="div" disablePadding>
{
props.exps.sort((a, b) => experimentInfo[a.name].order - experimentInfo[b.name].order).map((exp) =>
<Tooltip key={exp.name} title={exp.description}>
<Stack direction={"row"} alignItems={"center"}>
<ListItemText primary={"\u2022 " + exp.name} />
<InfoOutlined fontSize="small" />
</Stack>
</Tooltip>
)
}
</List>
</Collapse>
</List>
)
}

type ActiveExperimentListProps = { activeExps: { [key: string]: Experiment_Data[] } }

export const ActiveExperimentList: React.FC<ActiveExperimentListProps> = (props: ActiveExperimentListProps) => {
const [open, setOpen] = useState(false)

const handleClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
event.stopPropagation()
setOpen(!open);
};

return (
<List disablePadding>
<ListItemButton onClick={(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => handleClick(event)}>
<ListItemText primary={"Active in " + Object.values(props.activeExps).flat().length + " experiments"} />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open} timeout="auto" unmountOnExit>
<List sx={{ pl: 2 }} component="div" disablePadding>
{
Object.entries(props.activeExps).map(([grouping, exps]: [string, Experiment_Data[]]) =>
<ExperimentGroupList key={grouping} exps={exps} grouping={grouping} />
)
}
</List>
</Collapse>
</List>
)
}

type ActiveCellTypesListProps = { celltypes: CellQueryValue[] }

export const ActiveCellTypesList: React.FC<ActiveCellTypesListProps> = (props: ActiveCellTypesListProps) => {
const [open, setOpen] = useState(false)

const celltypes = [... new Set(props.celltypes.map(x => getCellDisplayName(x, true)))].sort()

const handleClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
event.stopPropagation()
setOpen(!open);
};

return (
<List disablePadding>
<ListItemButton onClick={(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => handleClick(event)}>
<ListItemText primary={"Active in " + celltypes.length + " immune cell types"} />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open} timeout="auto" unmountOnExit>
<List sx={{ pl: 2 }} component="div" disablePadding>
{
celltypes.map((cell: string) =>
<ListItemText key={cell} primary={"\u2022 " + cell} />
)
}
</List>
</Collapse>
</List>
)
}
11 changes: 9 additions & 2 deletions immuscreen/src/common/components/HomeAppBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ThemeProvider } from "@mui/material/styles"
import Link from "next/link"
import nextConfig from "../../../next.config"
import { defaultTheme } from "../lib/themes"
import Image from 'next/image'

const pageLinks = [
{
Expand Down Expand Up @@ -82,7 +83,7 @@ const HomeAppBar = () => {
<Container maxWidth={false}>
<Toolbar disableGutters sx={{ justifyContent: "center"}}>

<Typography
{/* <Typography
variant="h5"
noWrap
component="a"
Expand All @@ -102,7 +103,13 @@ const HomeAppBar = () => {
}}
>
igSCREEN
</Typography>
</Typography> */}
<Image
src="/igSCREEN.png"
width={116}
height={50}
alt="igSCREEN logo"
/>

<Box sx={{ flexGrow: 0, display: { xs: "inline", md: "none" } }}>
{/* Hamburger Menu, open on click */}
Expand Down

0 comments on commit 26b3d2c

Please sign in to comment.