From 72d85d746fd62a4b36555167735fd693fdd3e737 Mon Sep 17 00:00:00 2001 From: Graham McNeill Date: Wed, 25 Sep 2024 16:22:28 +0100 Subject: [PATCH 01/13] add credible set page --- .../pages/CredibleSetPage/CredibleSetPage.gql | 10 +++ .../pages/CredibleSetPage/CredibleSetPage.tsx | 77 +++++++++++++++++++ .../src/pages/CredibleSetPage/index.ts | 1 + 3 files changed, 88 insertions(+) create mode 100644 apps/platform/src/pages/CredibleSetPage/CredibleSetPage.gql create mode 100644 apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx create mode 100644 apps/platform/src/pages/CredibleSetPage/index.ts diff --git a/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.gql b/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.gql new file mode 100644 index 000000000..3fab96833 --- /dev/null +++ b/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.gql @@ -0,0 +1,10 @@ +query CredibleSetPageQuery($studyLocusIds: [String!]!) { + credibleSets(studyLocusIds: $studyLocusIds) { + variant { + id + } + study { + id + } + } +} \ No newline at end of file diff --git a/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx b/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx new file mode 100644 index 000000000..f9c0f6ea7 --- /dev/null +++ b/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx @@ -0,0 +1,77 @@ +import { Suspense } from "react"; +import { useQuery } from "@apollo/client"; +import { + useLocation, + useParams, + Switch, + Route, + useRouteMatch, + Link, +} from "react-router-dom"; +import { Box, Tabs, Tab } from "@mui/material"; +import { BasePage, ScrollToTop, LoadingBackdrop } from "ui"; +import Header from "./Header"; +import NotFoundPage from "../NotFoundPage"; +import CREDIBLE_SET_PAGE_QUERY from "./CredibleSetPage.gql"; +import Profile from "./Profile"; + +function CredibleSetPage() { + const location = useLocation(); + const { studyLocusId } = useParams() as { studyLocusId: string }; + const { path } = useRouteMatch(); + + const { loading, data } = useQuery(CREDIBLE_SET_PAGE_QUERY, { + variables: { studyLocusIds: [studyLocusId] }, + }); + + if (data && !data?.credibleSets.length) { + return ; + } + + const credibleSet = data.credibleSets[0]; + const variantId = credibleSet.variant?.id; + const studyId = credibleSet.study?.studyId; + + return ( + +
+ + ( + + + Profile} + value={`/credible-set/${studyLocusId}`} + component={Link} + to={`/credible-set/${studyLocusId}`} + /> + + + )} + /> + }> + + + + + + + + ); +} + +export default CredibleSetPage; diff --git a/apps/platform/src/pages/CredibleSetPage/index.ts b/apps/platform/src/pages/CredibleSetPage/index.ts new file mode 100644 index 000000000..abed1aace --- /dev/null +++ b/apps/platform/src/pages/CredibleSetPage/index.ts @@ -0,0 +1 @@ +export { default } from "./CredibleSetPage"; From b3092f73a83fac69fefef6eb1b78b01c2b893897 Mon Sep 17 00:00:00 2001 From: Graham McNeill Date: Thu, 26 Sep 2024 14:44:57 +0100 Subject: [PATCH 02/13] header and profile --- .../pages/CredibleSetPage/CredibleSetPage.gql | 4 +- .../pages/CredibleSetPage/CredibleSetPage.tsx | 3 +- .../src/pages/CredibleSetPage/Header.tsx | 110 ++++++++++++++++++ .../src/pages/CredibleSetPage/Profile.tsx | 67 +++++++++++ .../pages/CredibleSetPage/ProfileHeader.gql | 24 ++++ .../pages/CredibleSetPage/ProfileHeader.tsx | 101 ++++++++++++++++ 6 files changed, 307 insertions(+), 2 deletions(-) create mode 100644 apps/platform/src/pages/CredibleSetPage/Header.tsx create mode 100644 apps/platform/src/pages/CredibleSetPage/Profile.tsx create mode 100644 apps/platform/src/pages/CredibleSetPage/ProfileHeader.gql create mode 100644 apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx diff --git a/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.gql b/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.gql index 3fab96833..a64f5ea66 100644 --- a/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.gql +++ b/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.gql @@ -1,7 +1,9 @@ query CredibleSetPageQuery($studyLocusIds: [String!]!) { credibleSets(studyLocusIds: $studyLocusIds) { variant { - id + id, + referenceAllele, + alternateAllele } study { id diff --git a/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx b/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx index f9c0f6ea7..6581ad592 100644 --- a/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx +++ b/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx @@ -43,9 +43,10 @@ function CredibleSetPage() { >
`https://gnomad.broadinstitute.org/variant/${id}?dataset=gnomad_r4`, +// }, +// protvar: { +// label: "ProtVar", +// urlBuilder: (id, { chromosome, position, referenceAllele, alternateAllele }) => ( +// `https://www.ebi.ac.uk/ProtVar/query?chromosome=${chromosome +// }&genomic_position=${position +// }&reference_allele=${referenceAllele +// }&alternative_allele=${alternateAllele}` +// ), +// }, +// clinvar: { +// label: "ClinVar", +// urlStem: "https://www.ncbi.nlm.nih.gov/clinvar/variation/", +// }, +// omim: { +// label: "OMIM", +// urlStem: "https://www.omim.org/entry/", +// }, +// }; + +// function processXRefs(dbXRefs) { +// const xrefs = {}; +// for (const { id, source } of dbXRefs) { +// const { label, urlBuilder, urlStem } = xrefsToDisplay[source]; +// if (xrefs[source]) { +// xrefs[source].ids.add(id); +// } else { +// xrefs[source] = { +// label, +// urlStem, +// urlBuilder, +// ids: new Set([id]), +// }; +// } +// } +// return xrefs; +// } + +type HeaderProps = { + loading: boolean; + studyLocusId: string; + variantId: string; + referenceAllele: string; + alternateAllele: string; + studyId: string; +}; + +function Header({ + loading, + variantId, + referenceAllele, + alternateAllele, + studyId + }: HeaderProps) { + + // const xrefs = processXRefs(variantPageData?.dbXrefs || []); + + return ( + + Credible set around{" "} + + {" "}for study {studyId} + + } + Icon={faDiagramProject} + externalLinks={ + <> + + } + url={`../variant/${variantId}`} + /> + + + } + /> + ); +} + +export default Header; \ No newline at end of file diff --git a/apps/platform/src/pages/CredibleSetPage/Profile.tsx b/apps/platform/src/pages/CredibleSetPage/Profile.tsx new file mode 100644 index 000000000..308f25ecf --- /dev/null +++ b/apps/platform/src/pages/CredibleSetPage/Profile.tsx @@ -0,0 +1,67 @@ +import { Suspense, lazy } from "react"; +import { gql } from "@apollo/client"; +import { + PlatformApiProvider, + SectionContainer, + SummaryContainer, + SectionLoader, + summaryUtils, +} from "ui"; + +// import PharmacogenomicsSummary from "sections/src/variant/Pharmacogenomics/Summary"; + +import client from "../../client"; +import ProfileHeader from "./ProfileHeader"; +// const PharmacogenomicsSection = lazy( +// () => import("sections/src/variant/Pharmacogenomics/Body") +// ); + +const summaries = [ + // PharmacogenomicsSummary, +]; + +const CREDIBLE_SET = "credibleSets"; +const CREDIBLE_SET_PROFILE_SUMMARY_FRAGMENT = summaryUtils.createSummaryFragment( + summaries, + "credibleSet" +); +const CREDIBLE_SET_PROFILE_QUERY = gql` + query CredibleSetProfileQuery($studyLocusIds: [String!]!) { + credibleSets(studyLosucIds: $studyLocusIds) { + studyLocusId + ...CredibleSetProfileHeaderFragment + ...CredibleSetProfileSummaryFragment + } + } + ${ProfileHeader.fragments.profileHeader} + ${CREDIBLE_SET_PROFILE_SUMMARY_FRAGMENT} +`; + +type ProfileProps = { + studyLocusId: string; +}; + +function Profile({ studyLocusId }: ProfileProps) { + return ( + + + + + {/* */} + + + + {/* }> + + */} + + + ); +} + +export default Profile; diff --git a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.gql b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.gql new file mode 100644 index 000000000..b9f514d94 --- /dev/null +++ b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.gql @@ -0,0 +1,24 @@ +fragment CredibleSetProfileHeaderFragment on credibleSet { + pValueMantissa + pValueExponent + beta + standardError + effectAlleleFrequencyFromSource + locus { + posteriorProbability + variant { + id + chromosome + position + } + } + fineMappingMethod + credibleSetIndex + purityMinR2 + locusStart + locusEnd + study { + publicationFirstAuthor + publicationDate + } +} \ No newline at end of file diff --git a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx new file mode 100644 index 000000000..bc408b8e7 --- /dev/null +++ b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx @@ -0,0 +1,101 @@ +import { Fragment } from "react"; +import { + usePlatformApi, + Field, + ProfileHeader as BaseProfileHeader, + Link, + ScientificNotation, +} from "ui"; +import { Box, Typography, Skeleton } from "@mui/material"; +import { identifiersOrgLink } from "../../utils/global"; +import CREDIBLE_SET_PROFILE_HEADER_FRAGMENT from "./ProfileHeader.gql"; + +function ProfileHeader() { + + const { loading, error, data } = usePlatformApi(); + + // TODO: Errors! + if (error) return null; + + return ( + + + + + Lead Variant + + + + + data?.beta.toPrecision(3); + + + data?.standardError.toPrecision(3); + + + data?.effectAlleleFrequencyFromSource.toPrecision(3); + + + data?.posteriorProbability.toPrecision(3); + + + {data?.variant.chromosome}:{data?.variant.position} + + { + data?.variant?.rsIds.length > 0 && + + { + data.variant.rsIds.map((rsid, index) => ( + + {index > 0 && ", "} + + {rsid} + + + )) + } + + } + + + Credible Set + + {data?.finemappingMethod} + + + {data?.credibleSetIndex} + + + {data?.purityMinR2.toPrecision(3)} + + + {data?.locusStart} + + + {data?.locusEnd} + + + + + + Study + + {data?.study?.publicationFirstAuthor} + + + {data?.study?.publicationFirstAuthor?.slice(0, 4)} + + + + + ) +} + +ProfileHeader.fragments = { + profileHeader: CREDIBLE_SET_PROFILE_HEADER_FRAGMENT, +}; + +export default ProfileHeader; \ No newline at end of file From d9e5e09dcdcc085a8d9b1643feef03d8788851d6 Mon Sep 17 00:00:00 2001 From: Graham McNeill Date: Fri, 27 Sep 2024 12:03:36 +0100 Subject: [PATCH 03/13] finish metadata draft --- apps/platform/src/App.tsx | 4 + .../pages/CredibleSetPage/CredibleSetPage.gql | 2 +- .../pages/CredibleSetPage/CredibleSetPage.tsx | 12 +-- .../src/pages/CredibleSetPage/Header.tsx | 2 +- .../src/pages/CredibleSetPage/Profile.tsx | 10 ++- .../pages/CredibleSetPage/ProfileHeader.gql | 20 ++++- .../pages/CredibleSetPage/ProfileHeader.tsx | 80 +++++++++++++------ packages/ui/src/components/Summary/utils.js | 9 ++- 8 files changed, 98 insertions(+), 41 deletions(-) diff --git a/apps/platform/src/App.tsx b/apps/platform/src/App.tsx index fa127b8d4..a0aa09ed3 100644 --- a/apps/platform/src/App.tsx +++ b/apps/platform/src/App.tsx @@ -15,6 +15,7 @@ import TargetPage from "./pages/TargetPage"; import EvidencePage from "./pages/EvidencePage"; import VariantPage from "./pages/VariantPage"; import StudyPage from "./pages/StudyPage"; +import CredibleSetPage from "./pages/CredibleSetPage"; import APIPage from "./pages/APIPage"; import NotFoundPage from "./pages/NotFoundPage"; import ProjectsPage from "./pages/ProjectsPage"; @@ -61,6 +62,9 @@ function App(): ReactElement { + + + diff --git a/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.gql b/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.gql index a64f5ea66..9767b96a9 100644 --- a/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.gql +++ b/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.gql @@ -6,7 +6,7 @@ query CredibleSetPageQuery($studyLocusIds: [String!]!) { alternateAllele } study { - id + studyId } } } \ No newline at end of file diff --git a/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx b/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx index 6581ad592..8ce7d7bfc 100644 --- a/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx +++ b/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx @@ -28,9 +28,9 @@ function CredibleSetPage() { return ; } - const credibleSet = data.credibleSets[0]; - const variantId = credibleSet.variant?.id; - const studyId = credibleSet.study?.studyId; + const credibleSet = data?.credibleSets[0]; + const variantId = credibleSet?.variant?.id; + const studyId = credibleSet?.study?.studyId; return ( }> - + diff --git a/apps/platform/src/pages/CredibleSetPage/Header.tsx b/apps/platform/src/pages/CredibleSetPage/Header.tsx index 01c325562..7be8aa5e3 100644 --- a/apps/platform/src/pages/CredibleSetPage/Header.tsx +++ b/apps/platform/src/pages/CredibleSetPage/Header.tsx @@ -99,7 +99,7 @@ function Header({ } diff --git a/apps/platform/src/pages/CredibleSetPage/Profile.tsx b/apps/platform/src/pages/CredibleSetPage/Profile.tsx index 308f25ecf..894188a65 100644 --- a/apps/platform/src/pages/CredibleSetPage/Profile.tsx +++ b/apps/platform/src/pages/CredibleSetPage/Profile.tsx @@ -23,11 +23,12 @@ const summaries = [ const CREDIBLE_SET = "credibleSets"; const CREDIBLE_SET_PROFILE_SUMMARY_FRAGMENT = summaryUtils.createSummaryFragment( summaries, - "credibleSet" + "credibleSet", + "CredibleSetProfileSummaryFragment" ); const CREDIBLE_SET_PROFILE_QUERY = gql` query CredibleSetProfileQuery($studyLocusIds: [String!]!) { - credibleSets(studyLosucIds: $studyLocusIds) { + credibleSets(studyLocusIds: $studyLocusIds) { studyLocusId ...CredibleSetProfileHeaderFragment ...CredibleSetProfileSummaryFragment @@ -39,9 +40,10 @@ const CREDIBLE_SET_PROFILE_QUERY = gql` type ProfileProps = { studyLocusId: string; + variantId: string; }; -function Profile({ studyLocusId }: ProfileProps) { +function Profile({ studyLocusId, variantId }: ProfileProps) { return ( - + {/* */} diff --git a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.gql b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.gql index b9f514d94..ac45f7aa9 100644 --- a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.gql +++ b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.gql @@ -8,11 +8,14 @@ fragment CredibleSetProfileHeaderFragment on credibleSet { posteriorProbability variant { id - chromosome - position } } - fineMappingMethod + variant { + chromosome + position + rsIds + } + finemappingMethod credibleSetIndex purityMinR2 locusStart @@ -20,5 +23,16 @@ fragment CredibleSetProfileHeaderFragment on credibleSet { study { publicationFirstAuthor publicationDate + traitFromSource + target { + id + approvedSymbol + } + biosample { + biosampleId + } + publicationJournal + pubmedId + nSamples } } \ No newline at end of file diff --git a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx index bc408b8e7..2eef99632 100644 --- a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx +++ b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx @@ -6,47 +6,57 @@ import { Link, ScientificNotation, } from "ui"; -import { Box, Typography, Skeleton } from "@mui/material"; -import { identifiersOrgLink } from "../../utils/global"; +import { Box, Typography } from "@mui/material"; import CREDIBLE_SET_PROFILE_HEADER_FRAGMENT from "./ProfileHeader.gql"; +import { getStudyCategory } from "sections/src/utils/getStudyCategory"; -function ProfileHeader() { +type ProfileHeaderProps = { + variantId: string; +}; + +function ProfileHeader({ variantId }: ProfileHeaderProps) { const { loading, error, data } = usePlatformApi(); // TODO: Errors! if (error) return null; + const credibleSet = data?.credibleSets?.[0]; + const study = credibleSet?.study; + const studyCategory = study ? getStudyCategory(study) : null; + const target = study?.target; + const posteriorProbability = + credibleSet?.locus?.find(loc => loc?.variant.id === variantId)?.posteriorProbability; + return ( - Lead Variant - + - data?.beta.toPrecision(3); + {credibleSet?.beta?.toPrecision(3)} - data?.standardError.toPrecision(3); + {credibleSet?.standardError?.toPrecision(3)} - data?.effectAlleleFrequencyFromSource.toPrecision(3); + {credibleSet?.effectAlleleFrequencyFromSource?.toPrecision(3)} - data?.posteriorProbability.toPrecision(3); + {posteriorProbability?.toPrecision(3)} - {data?.variant.chromosome}:{data?.variant.position} + {credibleSet?.variant?.chromosome}:{credibleSet?.variant?.position} { - data?.variant?.rsIds.length > 0 && + credibleSet?.variant?.rsIds.length > 0 && { - data.variant.rsIds.map((rsid, index) => ( - + credibleSet.variant.rsIds.map((rsid, index) => ( + {index > 0 && ", "} } - - Credible Set + Credible Set - {data?.finemappingMethod} + {credibleSet?.finemappingMethod} - {data?.credibleSetIndex} + {credibleSet?.credibleSetIndex} - {data?.purityMinR2.toPrecision(3)} + {credibleSet?.purityMinR2?.toPrecision(3)} - {data?.locusStart} + {credibleSet?.locusStart} - {data?.locusEnd} + {credibleSet?.locusEnd} - Study - {data?.study?.publicationFirstAuthor} + {study?.publicationFirstAuthor} - {data?.study?.publicationFirstAuthor?.slice(0, 4)} + {study?.publicationDate?.slice(0, 4)} + + + {study?.traitFromSource} + + {studyCategory === "QTL" && + <> + {target?.id && + + + study?.target.approvedSymbol + + + } + + {study?.biosample?.biosampleId} + + + } + + {study?.publicationJournal} + + + {study?.pubmedId} + + + {study?.nSamples} diff --git a/packages/ui/src/components/Summary/utils.js b/packages/ui/src/components/Summary/utils.js index 0cbff5bc0..53c15a6f5 100644 --- a/packages/ui/src/components/Summary/utils.js +++ b/packages/ui/src/components/Summary/utils.js @@ -14,14 +14,17 @@ export function createSummaryFragment(sections, entity, fragmentName) { sectionFragments.push(Summary.fragments[sectionFragmentName]); }); + const idLookup = { + Gwas: 'studyId', + credibleSet: 'studyLocusId', + } + return gql` fragment ${fragmentNameStr} on ${entity} { ${ sectionFragmentNames.length ? sectionFragmentNames.map(sfn => `...${sfn}`).join("\n") - : entity === "Gwas" - ? "studyId" - : "id" + : idLookup[entity] || 'id' } } ${sectionFragments.reduce( From 981a80e9137c9172e8da6fafce5205fffd04ebc2 Mon Sep 17 00:00:00 2001 From: Graham McNeill Date: Mon, 30 Sep 2024 14:01:34 +0100 Subject: [PATCH 04/13] finish metadata --- .../pages/CredibleSetPage/CredibleSetPage.tsx | 4 +- .../src/pages/CredibleSetPage/Header.tsx | 66 +++---------------- .../pages/CredibleSetPage/ProfileHeader.tsx | 10 +-- 3 files changed, 16 insertions(+), 64 deletions(-) diff --git a/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx b/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx index 8ce7d7bfc..469bcd757 100644 --- a/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx +++ b/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx @@ -45,8 +45,8 @@ function CredibleSetPage() { loading={loading} studyId={studyId} variantId={variantId} - referenceAllele={credibleSet?.variant.referenceAllele} - alternateAllele={credibleSet?.variant.alternateAllele} + referenceAllele={credibleSet?.variant?.referenceAllele} + alternateAllele={credibleSet?.variant?.alternateAllele} /> `https://gnomad.broadinstitute.org/variant/${id}?dataset=gnomad_r4`, -// }, -// protvar: { -// label: "ProtVar", -// urlBuilder: (id, { chromosome, position, referenceAllele, alternateAllele }) => ( -// `https://www.ebi.ac.uk/ProtVar/query?chromosome=${chromosome -// }&genomic_position=${position -// }&reference_allele=${referenceAllele -// }&alternative_allele=${alternateAllele}` -// ), -// }, -// clinvar: { -// label: "ClinVar", -// urlStem: "https://www.ncbi.nlm.nih.gov/clinvar/variation/", -// }, -// omim: { -// label: "OMIM", -// urlStem: "https://www.omim.org/entry/", -// }, -// }; - -// function processXRefs(dbXRefs) { -// const xrefs = {}; -// for (const { id, source } of dbXRefs) { -// const { label, urlBuilder, urlStem } = xrefsToDisplay[source]; -// if (xrefs[source]) { -// xrefs[source].ids.add(id); -// } else { -// xrefs[source] = { -// label, -// urlStem, -// urlBuilder, -// ids: new Set([id]), -// }; -// } -// } -// return xrefs; -// } +import { Header as HeaderBase, DisplayVariantId, ExternalLink } from "ui"; type HeaderProps = { loading: boolean; - studyLocusId: string; variantId: string; referenceAllele: string; alternateAllele: string; @@ -64,8 +17,6 @@ function Header({ studyId }: HeaderProps) { - // const xrefs = processXRefs(variantPageData?.dbXrefs || []); - return ( {" "}for study {studyId} @@ -86,13 +36,13 @@ function Header({ <> + id={variantId && + } url={`../variant/${variantId}`} /> diff --git a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx index 2eef99632..f31d834ff 100644 --- a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx +++ b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx @@ -26,7 +26,7 @@ function ProfileHeader({ variantId }: ProfileHeaderProps) { const studyCategory = study ? getStudyCategory(study) : null; const target = study?.target; const posteriorProbability = - credibleSet?.locus?.find(loc => loc?.variant.id === variantId)?.posteriorProbability; + credibleSet?.locus?.find(loc => loc?.variant.id === variantId)?.posteriorProbability; return ( @@ -49,7 +49,9 @@ function ProfileHeader({ variantId }: ProfileHeaderProps) { {posteriorProbability?.toPrecision(3)} - {credibleSet?.variant?.chromosome}:{credibleSet?.variant?.position} + {credibleSet?.variant && + `${credibleSet.variant.chromosome}:${credibleSet.variant.position}` + } { credibleSet?.variant?.rsIds.length > 0 && @@ -104,7 +106,7 @@ function ProfileHeader({ variantId }: ProfileHeaderProps) { {target?.id && - study?.target.approvedSymbol + target.approvedSymbol } @@ -125,7 +127,7 @@ function ProfileHeader({ variantId }: ProfileHeaderProps) { - ) + ); } ProfileHeader.fragments = { From 3f6f52ca9713cff7cf1ef08cc0c12e36ed36620d Mon Sep 17 00:00:00 2001 From: Graham McNeill Date: Mon, 30 Sep 2024 16:44:53 +0100 Subject: [PATCH 05/13] consistent case in metadata --- .../src/pages/CredibleSetPage/ProfileHeader.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx index f31d834ff..0733d817c 100644 --- a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx +++ b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx @@ -39,13 +39,13 @@ function ProfileHeader({ variantId }: ProfileHeaderProps) { {credibleSet?.beta?.toPrecision(3)} - + {credibleSet?.standardError?.toPrecision(3)} {credibleSet?.effectAlleleFrequencyFromSource?.toPrecision(3)} - + {posteriorProbability?.toPrecision(3)} @@ -73,13 +73,13 @@ function ProfileHeader({ variantId }: ProfileHeaderProps) { } Credible Set - + {credibleSet?.finemappingMethod} - + {credibleSet?.credibleSetIndex} - + {credibleSet?.purityMinR2?.toPrecision(3)} @@ -121,7 +121,7 @@ function ProfileHeader({ variantId }: ProfileHeaderProps) { {study?.pubmedId} - + {study?.nSamples} From ac9432ea5bc0600b26dd96eb692979ddccc220f0 Mon Sep 17 00:00:00 2001 From: Graham McNeill Date: Tue, 1 Oct 2024 16:47:37 +0100 Subject: [PATCH 06/13] add variants widget to credible sets page --- .../src/pages/CredibleSetPage/Profile.tsx | 18 +- .../src/credibleSet/Variants/Body.tsx | 158 ++++++++++++++++++ .../src/credibleSet/Variants/Description.tsx | 14 ++ .../src/credibleSet/Variants/Summary.tsx | 16 ++ .../credibleSet/Variants/VariantsQuery.gql | 23 +++ .../Variants/VariantsSummaryFragment.gql | 5 + .../src/credibleSet/Variants/index.ts | 7 + 7 files changed, 232 insertions(+), 9 deletions(-) create mode 100644 packages/sections/src/credibleSet/Variants/Body.tsx create mode 100644 packages/sections/src/credibleSet/Variants/Description.tsx create mode 100644 packages/sections/src/credibleSet/Variants/Summary.tsx create mode 100644 packages/sections/src/credibleSet/Variants/VariantsQuery.gql create mode 100644 packages/sections/src/credibleSet/Variants/VariantsSummaryFragment.gql create mode 100644 packages/sections/src/credibleSet/Variants/index.ts diff --git a/apps/platform/src/pages/CredibleSetPage/Profile.tsx b/apps/platform/src/pages/CredibleSetPage/Profile.tsx index 894188a65..dcd0b6ecb 100644 --- a/apps/platform/src/pages/CredibleSetPage/Profile.tsx +++ b/apps/platform/src/pages/CredibleSetPage/Profile.tsx @@ -8,16 +8,16 @@ import { summaryUtils, } from "ui"; -// import PharmacogenomicsSummary from "sections/src/variant/Pharmacogenomics/Summary"; +import VariantsSummary from "sections/src/variant/Variants/Summary"; import client from "../../client"; import ProfileHeader from "./ProfileHeader"; -// const PharmacogenomicsSection = lazy( -// () => import("sections/src/variant/Pharmacogenomics/Body") -// ); +const VariantsSection = lazy( + () => import("sections/src/credibleSet/variants/Body") +); const summaries = [ - // PharmacogenomicsSummary, + VariantsSummary, ]; const CREDIBLE_SET = "credibleSets"; @@ -54,13 +54,13 @@ function Profile({ studyLocusId, variantId }: ProfileProps) { - {/* */} + - {/* }> - - */} + }> + + ); diff --git a/packages/sections/src/credibleSet/Variants/Body.tsx b/packages/sections/src/credibleSet/Variants/Body.tsx new file mode 100644 index 000000000..bd9e3a9d9 --- /dev/null +++ b/packages/sections/src/credibleSet/Variants/Body.tsx @@ -0,0 +1,158 @@ +import { useQuery } from "@apollo/client"; +import { + Link, + SectionItem, + DataTable, + ScientificNotation, + DisplayVariantId, +} from "ui"; +import { naLabel, defaultRowsPerPageOptions } from "../../constants"; +import { definition } from "."; +import Description from "./Description"; +import VARIANTS_QUERY from "./VariantsQuery.gql"; +import { variantComparator } from "../../utils/comparators"; + +const columns = [ + { + id: "variant.id", + label: "Variant ID", + comparator: variantComparator, + sortable: true, + filterValue: ({ variant: v }) => ( + `${v?.chromosome}_${v?.position}_${v?.referenceAllele}_${v?.alternateAllele}` + ), + renderCell: ({ variant }) => { + if (!variant) return naLabel; + const { id: variantId, referenceAllele, alternateAllele } = variant; + return + + ; + }, + exportValue: ({ variant }) => variant?.id, + }, + { + id: "pValue", + label: "P-value", + comparator: (a, b) => + a?.pValueMantissa * 10 ** a?.pValueExponent - + b?.pValueMantissa * 10 ** b?.pValueExponent, + sortable: true, + filterValue: false, + renderCell: ({ pValueMantissa, pValueExponent }) => { + if (typeof pValueMantissa !== "number" || + typeof pValueExponent !== "number") return naLabel; + return ; + }, + exportValue: ({ pValueMantissa, pValueExponent }) => { + if (typeof pValueMantissa !== "number" || + typeof pValueExponent !== "number") return null; + return `${pValueMantissa}x10${pValueExponent}`; + }, + }, + { + id: "beta", + label: "Beta", + filterValue: false, + tooltip: "Beta with respect to the ALT allele", + renderCell: ({ beta }) => { + if (typeof beta !== "number") return naLabel; + return beta.toPrecision(3); + }, + }, + { + id: "standardError", + label: "Standard error", + filterValue: false, + tooltip: "Standard Error: Estimate of the standard deviation of the sampling distribution of the beta", + renderCell: ({ standardError }) => { + if (typeof standardError !== "number") return naLabel; + return standardError.toPrecision(3); + }, + }, + { + id: "r2Overall", + label: "LD (r²)", + filterValue: false, + tooltip: <> + Linkage disequilibrium with the lead variant ( + + ). + , + renderCell: ({ r2Overall }) => { + if (typeof r2Overall !== "number") return naLabel; + return r2Overall.toPrecision(3); + }, + }, + { + id: "posteriorProbability", + label: "Posterior Probability", + filterValue: false, + tooltip: "Posterior inclusion probability from fine-mapping that this variant is causal", + comparator: (rowA, rowB) => rowA?.posteriorProbability - rowB?.posteriorProbability, + sortable: true, + renderCell: ({ posteriorProbability }) => { + if (typeof posteriorProbability !== "number") return naLabel; + return posteriorProbability.toPrecision(3); + }, + }, + { + id: 'logBF', + label: 'LOG(BF)', + filterValue: false, + renderCell: ({ logBF }) => { + if (typeof logBF !== "number") return naLabel; + return logBF.toPrecision(3); + }, + } +]; + +type BodyProps = { + id: string, + entity: string, +}; + +function Body({ id, entity }: BodyProps) { + const variables = { + studyLocusIds: [id], + }; + + const request = useQuery(VARIANTS_QUERY, { + variables, + }); + + return ( + } + renderBody={({ credibleSets }) => { + return ( + + ); + }} + /> + ); + +} + +export default Body; \ No newline at end of file diff --git a/packages/sections/src/credibleSet/Variants/Description.tsx b/packages/sections/src/credibleSet/Variants/Description.tsx new file mode 100644 index 000000000..75b9ed69d --- /dev/null +++ b/packages/sections/src/credibleSet/Variants/Description.tsx @@ -0,0 +1,14 @@ +import { Link } from "ui"; + +function Description() { + return ( + <> + Variants in the credible set. Source{" "} + + Open Targets + + + ); +} + +export default Description; \ No newline at end of file diff --git a/packages/sections/src/credibleSet/Variants/Summary.tsx b/packages/sections/src/credibleSet/Variants/Summary.tsx new file mode 100644 index 000000000..871af4c38 --- /dev/null +++ b/packages/sections/src/credibleSet/Variants/Summary.tsx @@ -0,0 +1,16 @@ +import { SummaryItem, usePlatformApi } from "ui"; + +import { definition } from "."; +import VARIANTS_SUMMARY from "./VariantsSummaryFragment.gql"; + +function Summary() { + const request = usePlatformApi(VARIANTS_SUMMARY); + + return ; +} + +Summary.fragments = { + VariantsSummaryFragment: VARIANTS_SUMMARY, +}; + +export default Summary; \ No newline at end of file diff --git a/packages/sections/src/credibleSet/Variants/VariantsQuery.gql b/packages/sections/src/credibleSet/Variants/VariantsQuery.gql new file mode 100644 index 000000000..57a0f9363 --- /dev/null +++ b/packages/sections/src/credibleSet/Variants/VariantsQuery.gql @@ -0,0 +1,23 @@ +query VariantsQuery($studyLocusIds: [String!]!) { + credibleSets(studyLocusIds $studyLocusIds) { + studyLocusId + locus { + is95CredibleSet + is99CredibleSet + logBF + posteriorProbability + variant { + id + chromosome + position + referenceAllele + alternateAllele + } + pValueMantissa + pValueExponent + beta + standardError + r2Overall + } + } +} \ No newline at end of file diff --git a/packages/sections/src/credibleSet/Variants/VariantsSummaryFragment.gql b/packages/sections/src/credibleSet/Variants/VariantsSummaryFragment.gql new file mode 100644 index 000000000..55d6fbeb4 --- /dev/null +++ b/packages/sections/src/credibleSet/Variants/VariantsSummaryFragment.gql @@ -0,0 +1,5 @@ +fragment VariantsSummaryFragment on credibleSet { + locus { + beta + } +} \ No newline at end of file diff --git a/packages/sections/src/credibleSet/Variants/index.ts b/packages/sections/src/credibleSet/Variants/index.ts new file mode 100644 index 000000000..ce2fe37fa --- /dev/null +++ b/packages/sections/src/credibleSet/Variants/index.ts @@ -0,0 +1,7 @@ +const id = "variants"; +export const definition = { + id, + name: "Variants", + shortName: "VA", + hasData: data => data?.[0]?.locus?.length > 0, +}; \ No newline at end of file From a8981a1fa826e311fd435b70e0c16bd4737fa34b Mon Sep 17 00:00:00 2001 From: Graham McNeill Date: Wed, 2 Oct 2024 12:05:21 +0100 Subject: [PATCH 07/13] variants widget fixes --- .../pages/CredibleSetPage/CredibleSetPage.tsx | 13 +- .../src/pages/CredibleSetPage/Profile.tsx | 21 +- .../src/credibleSet/Variants/Body.tsx | 233 ++++++++++-------- .../credibleSet/Variants/VariantsQuery.gql | 2 +- 4 files changed, 161 insertions(+), 108 deletions(-) diff --git a/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx b/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx index 469bcd757..bbb3a8a2e 100644 --- a/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx +++ b/apps/platform/src/pages/CredibleSetPage/CredibleSetPage.tsx @@ -30,6 +30,8 @@ function CredibleSetPage() { const credibleSet = data?.credibleSets[0]; const variantId = credibleSet?.variant?.id; + const referenceAllele = credibleSet?.variant?.referenceAllele + const alternateAllele = credibleSet?.variant?.alternateAllele const studyId = credibleSet?.study?.studyId; return ( @@ -45,8 +47,8 @@ function CredibleSetPage() { loading={loading} studyId={studyId} variantId={variantId} - referenceAllele={credibleSet?.variant?.referenceAllele} - alternateAllele={credibleSet?.variant?.alternateAllele} + referenceAllele={referenceAllele} + alternateAllele={alternateAllele} /> }> - + diff --git a/apps/platform/src/pages/CredibleSetPage/Profile.tsx b/apps/platform/src/pages/CredibleSetPage/Profile.tsx index dcd0b6ecb..b2afb4370 100644 --- a/apps/platform/src/pages/CredibleSetPage/Profile.tsx +++ b/apps/platform/src/pages/CredibleSetPage/Profile.tsx @@ -8,7 +8,7 @@ import { summaryUtils, } from "ui"; -import VariantsSummary from "sections/src/variant/Variants/Summary"; +import VariantsSummary from "sections/src/credibleSet/Variants/Summary"; import client from "../../client"; import ProfileHeader from "./ProfileHeader"; @@ -41,9 +41,17 @@ const CREDIBLE_SET_PROFILE_QUERY = gql` type ProfileProps = { studyLocusId: string; variantId: string; + referenceAllele: string; + alternateAllele: string; }; -function Profile({ studyLocusId, variantId }: ProfileProps) { +function Profile({ + studyLocusId, + variantId, + referenceAllele, + alternateAllele, + }: ProfileProps) { + return ( }> - + ); + } export default Profile; diff --git a/packages/sections/src/credibleSet/Variants/Body.tsx b/packages/sections/src/credibleSet/Variants/Body.tsx index bd9e3a9d9..fed6c277c 100644 --- a/packages/sections/src/credibleSet/Variants/Body.tsx +++ b/packages/sections/src/credibleSet/Variants/Body.tsx @@ -12,124 +12,154 @@ import Description from "./Description"; import VARIANTS_QUERY from "./VariantsQuery.gql"; import { variantComparator } from "../../utils/comparators"; -const columns = [ - { - id: "variant.id", - label: "Variant ID", - comparator: variantComparator, - sortable: true, - filterValue: ({ variant: v }) => ( - `${v?.chromosome}_${v?.position}_${v?.referenceAllele}_${v?.alternateAllele}` - ), - renderCell: ({ variant }) => { - if (!variant) return naLabel; - const { id: variantId, referenceAllele, alternateAllele } = variant; - return - - ; - }, - exportValue: ({ variant }) => variant?.id, - }, - { - id: "pValue", - label: "P-value", - comparator: (a, b) => - a?.pValueMantissa * 10 ** a?.pValueExponent - - b?.pValueMantissa * 10 ** b?.pValueExponent, - sortable: true, - filterValue: false, - renderCell: ({ pValueMantissa, pValueExponent }) => { - if (typeof pValueMantissa !== "number" || - typeof pValueExponent !== "number") return naLabel; - return ; - }, - exportValue: ({ pValueMantissa, pValueExponent }) => { - if (typeof pValueMantissa !== "number" || - typeof pValueExponent !== "number") return null; - return `${pValueMantissa}x10${pValueExponent}`; +type getColumnsType = { + leadVariantId: string; + leadReferenceAllele: string; + leadAlternateAllele: string; +}; + +function getColumns({ + leadVariantId, + leadReferenceAllele, + leadAlternateAllele, + }: getColumnsType) { + + return [ + { + id: "variant.id", + label: "Variant ID", + comparator: variantComparator, + sortable: true, + filterValue: ({ variant: v }) => ( + `${v?.chromosome}_${v?.position}_${v?.referenceAllele}_${v?.alternateAllele}` + ), + renderCell: ({ variant }) => { + if (!variant) return naLabel; + const { id: variantId, referenceAllele, alternateAllele } = variant; + return + + ; + }, + exportValue: ({ variant }) => variant?.id, }, - }, - { - id: "beta", - label: "Beta", - filterValue: false, - tooltip: "Beta with respect to the ALT allele", - renderCell: ({ beta }) => { - if (typeof beta !== "number") return naLabel; - return beta.toPrecision(3); + { + id: "pValue", + label: "P-value", + comparator: (a, b) => + a?.pValueMantissa * 10 ** a?.pValueExponent - + b?.pValueMantissa * 10 ** b?.pValueExponent, + sortable: true, + filterValue: false, + renderCell: ({ pValueMantissa, pValueExponent }) => { + if (typeof pValueMantissa !== "number" || + typeof pValueExponent !== "number") return naLabel; + return ; + }, + exportValue: ({ pValueMantissa, pValueExponent }) => { + if (typeof pValueMantissa !== "number" || + typeof pValueExponent !== "number") return null; + return `${pValueMantissa}x10${pValueExponent}`; + }, }, - }, - { - id: "standardError", - label: "Standard error", - filterValue: false, - tooltip: "Standard Error: Estimate of the standard deviation of the sampling distribution of the beta", - renderCell: ({ standardError }) => { - if (typeof standardError !== "number") return naLabel; - return standardError.toPrecision(3); + { + id: "beta", + label: "Beta", + filterValue: false, + tooltip: "Beta with respect to the ALT allele", + renderCell: ({ beta }) => { + if (typeof beta !== "number") return naLabel; + return beta.toPrecision(3); + }, }, - }, - { - id: "r2Overall", - label: "LD (r²)", - filterValue: false, - tooltip: <> - Linkage disequilibrium with the lead variant ( - - ). - , - renderCell: ({ r2Overall }) => { - if (typeof r2Overall !== "number") return naLabel; - return r2Overall.toPrecision(3); + { + id: "standardError", + label: "Standard error", + filterValue: false, + tooltip: "Standard Error: Estimate of the standard deviation of the sampling distribution of the beta", + renderCell: ({ standardError }) => { + if (typeof standardError !== "number") return naLabel; + return standardError.toPrecision(3); + }, }, - }, - { - id: "posteriorProbability", - label: "Posterior Probability", - filterValue: false, - tooltip: "Posterior inclusion probability from fine-mapping that this variant is causal", - comparator: (rowA, rowB) => rowA?.posteriorProbability - rowB?.posteriorProbability, - sortable: true, - renderCell: ({ posteriorProbability }) => { - if (typeof posteriorProbability !== "number") return naLabel; - return posteriorProbability.toPrecision(3); + { + id: "r2Overall", + label: "LD (r²)", + filterValue: false, + tooltip: <> + Linkage disequilibrium with the lead variant ( + + ). + , + renderCell: ({ r2Overall }) => { + if (typeof r2Overall !== "number") return naLabel; + return r2Overall.toPrecision(3); + }, }, - }, - { - id: 'logBF', - label: 'LOG(BF)', - filterValue: false, - renderCell: ({ logBF }) => { - if (typeof logBF !== "number") return naLabel; - return logBF.toPrecision(3); + { + id: "posteriorProbability", + label: "Posterior Probability", + filterValue: false, + tooltip: "Posterior inclusion probability from fine-mapping that this variant is causal", + comparator: (rowA, rowB) => rowA?.posteriorProbability - rowB?.posteriorProbability, + sortable: true, + renderCell: ({ posteriorProbability }) => { + if (typeof posteriorProbability !== "number") return naLabel; + return posteriorProbability.toPrecision(3); + }, }, - } -]; + { + id: 'logBF', + label: 'LOG(BF)', + filterValue: false, + renderCell: ({ logBF }) => { + if (typeof logBF !== "number") return naLabel; + return logBF.toPrecision(3); + }, + } + ]; + +} type BodyProps = { - id: string, + studyLocusId: string, + leadVariantId: string, + leadReferenceAllele: string, + leadAlternateAllele: string, entity: string, }; -function Body({ id, entity }: BodyProps) { +function Body({ + studyLocusId, + leadVariantId, + leadReferenceAllele, + leadAlternateAllele, + entity + }: BodyProps) { + const variables = { - studyLocusIds: [id], + studyLocusIds: [studyLocusId], }; const request = useQuery(VARIANTS_QUERY, { variables, }); + const columns = getColumns({ + leadVariantId, + leadReferenceAllele, + leadAlternateAllele, + }); + return ( } renderBody={({ credibleSets }) => { + // debugger return ( Date: Thu, 3 Oct 2024 18:17:12 +0100 Subject: [PATCH 08/13] header title and metadata tooltips --- .../src/pages/CredibleSetPage/Header.tsx | 26 ++---- .../pages/CredibleSetPage/ProfileHeader.gql | 4 + .../pages/CredibleSetPage/ProfileHeader.tsx | 93 +++++++++++++++---- 3 files changed, 88 insertions(+), 35 deletions(-) diff --git a/apps/platform/src/pages/CredibleSetPage/Header.tsx b/apps/platform/src/pages/CredibleSetPage/Header.tsx index 78016a95d..2b05d2222 100644 --- a/apps/platform/src/pages/CredibleSetPage/Header.tsx +++ b/apps/platform/src/pages/CredibleSetPage/Header.tsx @@ -20,29 +20,19 @@ function Header({ return ( - Credible set around{" "} - - {" "}for study {studyId} - - } + title="Credible set" Icon={faDiagramProject} externalLinks={ <> + } url={`../variant/${variantId}`} /> diff --git a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.gql b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.gql index ac45f7aa9..41a444e46 100644 --- a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.gql +++ b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.gql @@ -6,6 +6,10 @@ fragment CredibleSetProfileHeaderFragment on credibleSet { effectAlleleFrequencyFromSource locus { posteriorProbability + pValueMantissa + pValueExponent + beta + standardError variant { id } diff --git a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx index 0733d817c..40c563f29 100644 --- a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx +++ b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx @@ -5,6 +5,7 @@ import { ProfileHeader as BaseProfileHeader, Link, ScientificNotation, + Tooltip, } from "ui"; import { Box, Typography } from "@mui/material"; import CREDIBLE_SET_PROFILE_HEADER_FRAGMENT from "./ProfileHeader.gql"; @@ -25,29 +26,87 @@ function ProfileHeader({ variantId }: ProfileHeaderProps) { const study = credibleSet?.study; const studyCategory = study ? getStudyCategory(study) : null; const target = study?.target; - const posteriorProbability = - credibleSet?.locus?.find(loc => loc?.variant.id === variantId)?.posteriorProbability; + const leadVariant = credibleSet?.locus?.find(loc => loc?.variant.id === variantId); + const beta = leadVariant?.beta ?? credibleSet?.beta; + const standardError = leadVariant?.standardError ?? credibleSet?.standardError; + const { pValueMantissa, pValueExponent } = + typeof leadVariant?.pValueMantissa === "number" && + typeof leadVariant?.pValueExponent === "number" + ? leadVariant + : credibleSet ?? {}; return ( Lead Variant - - - - - {credibleSet?.beta?.toPrecision(3)} - - - {credibleSet?.standardError?.toPrecision(3)} - - - {credibleSet?.effectAlleleFrequencyFromSource?.toPrecision(3)} - - - {posteriorProbability?.toPrecision(3)} - + {typeof pValueMantissa === "number" && typeof pValueExponent === "number" && + + + + } + {typeof beta === 'number' && + + Beta with respect to the ALT allele + + } + showHelpIcon + > + Beta + + } + > + {beta.toPrecision(3)} + + } + {typeof standardError === 'number' && + + Standard error: Estimate of the standard deviation of the sampling distribution of the beta + + } + showHelpIcon + > + Standard error + + } + > + {standardError.toPrecision(3)} + + } + {typeof credibleSet?.effectAlleleFrequencyFromSource === "number" && + + {credibleSet.effectAlleleFrequencyFromSource.toPrecision(3)} + + } + {typeof leadVariant?.posteriorProbability === "number" && + + Posterior inclusion probability from fine-mapping that this variant is causal + + } + showHelpIcon + > + Posterior probability + + } + > + {leadVariant.posteriorProbability.toPrecision(3)} + + } {credibleSet?.variant && `${credibleSet.variant.chromosome}:${credibleSet.variant.position}` From ba9753168aca213221fc4cf3fe6cf4ba3cc460ba Mon Sep 17 00:00:00 2001 From: Graham McNeill Date: Thu, 3 Oct 2024 18:34:26 +0100 Subject: [PATCH 09/13] precision --- .../src/pages/CredibleSetPage/ProfileHeader.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx index 40c563f29..d0106dd7f 100644 --- a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx +++ b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx @@ -61,7 +61,7 @@ function ProfileHeader({ variantId }: ProfileHeaderProps) { } > - {beta.toPrecision(3)} + {beta.toPrecision(2)} } {typeof standardError === 'number' && @@ -80,12 +80,12 @@ function ProfileHeader({ variantId }: ProfileHeaderProps) { } > - {standardError.toPrecision(3)} + {standardError.toPrecision(2)} } {typeof credibleSet?.effectAlleleFrequencyFromSource === "number" && - {credibleSet.effectAlleleFrequencyFromSource.toPrecision(3)} + {credibleSet.effectAlleleFrequencyFromSource.toPrecision(2)} } {typeof leadVariant?.posteriorProbability === "number" && @@ -104,7 +104,7 @@ function ProfileHeader({ variantId }: ProfileHeaderProps) { } > - {leadVariant.posteriorProbability.toPrecision(3)} + {leadVariant.posteriorProbability.toPrecision(2)} } @@ -139,7 +139,7 @@ function ProfileHeader({ variantId }: ProfileHeaderProps) { {credibleSet?.credibleSetIndex} - {credibleSet?.purityMinR2?.toPrecision(3)} + {credibleSet?.purityMinR2?.toPrecision(2)} {credibleSet?.locusStart} From c1650ff54a511b3be127fe133766dafc4360eb9c Mon Sep 17 00:00:00 2001 From: Graham McNeill Date: Thu, 3 Oct 2024 19:21:04 +0100 Subject: [PATCH 10/13] update title and sort --- packages/sections/src/credibleSet/Variants/Body.tsx | 13 +++++++++++-- .../src/credibleSet/Variants/Description.tsx | 2 +- packages/sections/src/credibleSet/Variants/index.ts | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/sections/src/credibleSet/Variants/Body.tsx b/packages/sections/src/credibleSet/Variants/Body.tsx index fed6c277c..6edb7625f 100644 --- a/packages/sections/src/credibleSet/Variants/Body.tsx +++ b/packages/sections/src/credibleSet/Variants/Body.tsx @@ -1,4 +1,5 @@ import { useQuery } from "@apollo/client"; +import { Box, Chip } from "@mui/material"; import { Link, SectionItem, @@ -36,7 +37,7 @@ function getColumns({ renderCell: ({ variant }) => { if (!variant) return naLabel; const { id: variantId, referenceAllele, alternateAllele } = variant; - return + const displayElement = ; + if (variantId === leadVariantId) { + return + {displayElement} + + ; + } + return displayElement; }, exportValue: ({ variant }) => variant?.id, }, @@ -172,7 +180,8 @@ function Body({ - Variants in the credible set. Source{" "} + Source:{" "} Open Targets diff --git a/packages/sections/src/credibleSet/Variants/index.ts b/packages/sections/src/credibleSet/Variants/index.ts index ce2fe37fa..cf5933ced 100644 --- a/packages/sections/src/credibleSet/Variants/index.ts +++ b/packages/sections/src/credibleSet/Variants/index.ts @@ -1,7 +1,7 @@ const id = "variants"; export const definition = { id, - name: "Variants", + name: "Variants in Credible Set", shortName: "VA", hasData: data => data?.[0]?.locus?.length > 0, }; \ No newline at end of file From 5d61b4ea2fde539108bfd247a54a8d3e23351dc6 Mon Sep 17 00:00:00 2001 From: Graham McNeill Date: Thu, 3 Oct 2024 19:23:53 +0100 Subject: [PATCH 11/13] precsion to 3sf --- .../src/pages/CredibleSetPage/ProfileHeader.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx index d0106dd7f..40c563f29 100644 --- a/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx +++ b/apps/platform/src/pages/CredibleSetPage/ProfileHeader.tsx @@ -61,7 +61,7 @@ function ProfileHeader({ variantId }: ProfileHeaderProps) { } > - {beta.toPrecision(2)} + {beta.toPrecision(3)} } {typeof standardError === 'number' && @@ -80,12 +80,12 @@ function ProfileHeader({ variantId }: ProfileHeaderProps) { } > - {standardError.toPrecision(2)} + {standardError.toPrecision(3)} } {typeof credibleSet?.effectAlleleFrequencyFromSource === "number" && - {credibleSet.effectAlleleFrequencyFromSource.toPrecision(2)} + {credibleSet.effectAlleleFrequencyFromSource.toPrecision(3)} } {typeof leadVariant?.posteriorProbability === "number" && @@ -104,7 +104,7 @@ function ProfileHeader({ variantId }: ProfileHeaderProps) { } > - {leadVariant.posteriorProbability.toPrecision(2)} + {leadVariant.posteriorProbability.toPrecision(3)} } @@ -139,7 +139,7 @@ function ProfileHeader({ variantId }: ProfileHeaderProps) { {credibleSet?.credibleSetIndex} - {credibleSet?.purityMinR2?.toPrecision(2)} + {credibleSet?.purityMinR2?.toPrecision(3)} {credibleSet?.locusStart} From 601131d7b2cc562d84e69da0c5893a7d20adb817 Mon Sep 17 00:00:00 2001 From: Graham McNeill Date: Fri, 4 Oct 2024 09:29:59 +0100 Subject: [PATCH 12/13] remove query fields --- packages/sections/src/credibleSet/Variants/Body.tsx | 2 +- packages/sections/src/credibleSet/Variants/VariantsQuery.gql | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/sections/src/credibleSet/Variants/Body.tsx b/packages/sections/src/credibleSet/Variants/Body.tsx index 6edb7625f..12b3ffba4 100644 --- a/packages/sections/src/credibleSet/Variants/Body.tsx +++ b/packages/sections/src/credibleSet/Variants/Body.tsx @@ -106,7 +106,7 @@ function getColumns({ alternateAllele={leadAlternateAllele} expand={false} /> - ). + ) , renderCell: ({ r2Overall }) => { if (typeof r2Overall !== "number") return naLabel; diff --git a/packages/sections/src/credibleSet/Variants/VariantsQuery.gql b/packages/sections/src/credibleSet/Variants/VariantsQuery.gql index 016009364..2d15058a8 100644 --- a/packages/sections/src/credibleSet/Variants/VariantsQuery.gql +++ b/packages/sections/src/credibleSet/Variants/VariantsQuery.gql @@ -2,8 +2,6 @@ query VariantsQuery($studyLocusIds: [String!]!) { credibleSets(studyLocusIds: $studyLocusIds) { studyLocusId locus { - is95CredibleSet - is99CredibleSet logBF posteriorProbability variant { From a3a3f08fbba1f89e2222ee4f7b095712c07879e3 Mon Sep 17 00:00:00 2001 From: Graham McNeill Date: Fri, 4 Oct 2024 10:33:18 +0100 Subject: [PATCH 13/13] correct case for import --- apps/platform/src/pages/CredibleSetPage/Profile.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/platform/src/pages/CredibleSetPage/Profile.tsx b/apps/platform/src/pages/CredibleSetPage/Profile.tsx index b2afb4370..662e13b4b 100644 --- a/apps/platform/src/pages/CredibleSetPage/Profile.tsx +++ b/apps/platform/src/pages/CredibleSetPage/Profile.tsx @@ -13,7 +13,7 @@ import VariantsSummary from "sections/src/credibleSet/Variants/Summary"; import client from "../../client"; import ProfileHeader from "./ProfileHeader"; const VariantsSection = lazy( - () => import("sections/src/credibleSet/variants/Body") + () => import("sections/src/credibleSet/Variants/Body") ); const summaries = [