From b2c1f093c280be0da5a2fd2c7e71dc39fcc9ddac Mon Sep 17 00:00:00 2001
From: Sam Park
Date: Wed, 15 Jan 2025 12:09:10 -0500
Subject: [PATCH 1/5] add reference genome compatibility modal
---
ui/bedbase-types.d.ts | 93 ++++++++++++++++++-
.../bed-splash-components/header.tsx | 58 ++++++++++--
.../bed-splash-components/refgenome-modal.tsx | 52 +++++++++++
.../bed2bed/b2b-search-results-table.tsx | 4 +-
.../text2bed/t2b-search-results-table.tsx | 6 +-
ui/src/pages/bed-splash.tsx | 10 +-
ui/src/queries/useBedGenomeStats.ts | 29 ++++++
7 files changed, 235 insertions(+), 17 deletions(-)
create mode 100644 ui/src/components/bed-splash-components/refgenome-modal.tsx
create mode 100644 ui/src/queries/useBedGenomeStats.ts
diff --git a/ui/bedbase-types.d.ts b/ui/bedbase-types.d.ts
index fbf47a7..bece057 100644
--- a/ui/bedbase-types.d.ts
+++ b/ui/bedbase-types.d.ts
@@ -467,6 +467,27 @@ export interface paths {
patch?: never;
trace?: never;
};
+ "/v1/bed/{bed_id}/genome-stats": {
+ parameters: {
+ query?: never;
+ header?: never;
+ path?: never;
+ cookie?: never;
+ };
+ /**
+ * Get reference genome validation results
+ * @description Return reference genome validation results for a bed file
+ * Example: bed: 0dcdf8986a72a3d85805bbc9493a1302
+ */
+ get: operations["get_ref_gen_results_v1_bed__bed_id__genome_stats_get"];
+ put?: never;
+ post?: never;
+ delete?: never;
+ options?: never;
+ head?: never;
+ patch?: never;
+ trace?: never;
+ };
"/v1/bedset/example": {
parameters: {
query?: never;
@@ -909,7 +930,10 @@ export interface components {
};
/** BedPEPHub */
BedPEPHub: {
- /** Sample Name */
+ /**
+ * Sample Name
+ * @default
+ */
sample_name: string;
/**
* Genome
@@ -1001,7 +1025,10 @@ export interface components {
};
/** BedPEPHubRestrict */
BedPEPHubRestrict: {
- /** Sample Name */
+ /**
+ * Sample Name
+ * @default
+ */
sample_name: string;
/**
* Genome
@@ -1305,9 +1332,38 @@ export interface components {
/** Payload */
payload?: Record;
/** Score */
- score: number;
+ score?: number;
metadata?: components["schemas"]["BedMetadataBasic"] | null;
};
+ /** RefGenValidModel */
+ RefGenValidModel: {
+ /** Provided Genome */
+ provided_genome: string;
+ /** Compared Genome */
+ compared_genome: string;
+ /**
+ * Xs
+ * @default 0
+ */
+ xs: number;
+ /** Oobr */
+ oobr?: number | null;
+ /** Sequence Fit */
+ sequence_fit?: number | null;
+ /** Assigned Points */
+ assigned_points: number;
+ /** Tier Ranking */
+ tier_ranking: number;
+ };
+ /** RefGenValidReturnModel */
+ RefGenValidReturnModel: {
+ /** Id */
+ id: string;
+ /** Provided Genome */
+ provided_genome?: string | null;
+ /** Compared Genome */
+ compared_genome: components["schemas"]["RefGenValidModel"][];
+ };
/** ServiceInfoResponse */
ServiceInfoResponse: {
/** Id */
@@ -2174,6 +2230,37 @@ export interface operations {
};
};
};
+ get_ref_gen_results_v1_bed__bed_id__genome_stats_get: {
+ parameters: {
+ query?: never;
+ header?: never;
+ path: {
+ bed_id: string;
+ };
+ cookie?: never;
+ };
+ requestBody?: never;
+ responses: {
+ /** @description Successful Response */
+ 200: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content: {
+ "application/json": components["schemas"]["RefGenValidReturnModel"];
+ };
+ };
+ /** @description Validation Error */
+ 422: {
+ headers: {
+ [name: string]: unknown;
+ };
+ content: {
+ "application/json": components["schemas"]["HTTPValidationError"];
+ };
+ };
+ };
+ };
get_example_bedset_record_v1_bedset_example_get: {
parameters: {
query?: never;
diff --git a/ui/src/components/bed-splash-components/header.tsx b/ui/src/components/bed-splash-components/header.tsx
index c872647..9e8015c 100644
--- a/ui/src/components/bed-splash-components/header.tsx
+++ b/ui/src/components/bed-splash-components/header.tsx
@@ -5,23 +5,28 @@ import { components } from '../../../bedbase-types';
import { useCopyToClipboard } from '@uidotdev/usehooks';
import { bytesToSize, formatDateTime } from '../../utils';
import { Dropdown, OverlayTrigger } from 'react-bootstrap';
+import { RefGenomeModal } from './refgenome-modal';
const API_BASE = import.meta.env.VITE_API_BASE || '';
type BedMetadata = components['schemas']['BedMetadataAll'];
+type BedGenomeStats = components['schemas']['RefGenValidReturnModel'];
type Props = {
metadata: BedMetadata;
record_identifier: string | undefined;
+ genomeStats: BedGenomeStats;
};
export const BedSplashHeader = (props: Props) => {
- const { metadata, record_identifier } = props;
+ const { metadata, record_identifier, genomeStats } = props;
const [, copyToClipboard] = useCopyToClipboard();
const { cart, addBedToCart, removeBedFromCart } = useBedCart();
const [addedToCart, setAddedToCart] = useState(false);
const [copiedId, setCopiedId] = useState(false);
+ const [showRefGenomeModal, setShowRefGenomeModal] = useState(false);
+
const noFilesToDownload = !metadata.files?.bed_file && !metadata.files?.bigbed_file;
@@ -158,19 +163,47 @@ export const BedSplashHeader = (props: Props) => {
}
>
{metadata?.genome_digest ? (
-
-
+ }
+ >
+ {
+ // conditional required to prevent double click
+ if (showRefGenomeModal !== true) {
+ setShowRefGenomeModal(true);
+ }
+ }}
+ >
+
+
+
+ }
@@ -271,6 +304,13 @@ export const BedSplashHeader = (props: Props) => {
+ {
+ setShowRefGenomeModal(false);
+ }}
+ genomeStats={genomeStats}
+ />
);
};
diff --git a/ui/src/components/bed-splash-components/refgenome-modal.tsx b/ui/src/components/bed-splash-components/refgenome-modal.tsx
new file mode 100644
index 0000000..bad88e2
--- /dev/null
+++ b/ui/src/components/bed-splash-components/refgenome-modal.tsx
@@ -0,0 +1,52 @@
+import { Modal } from 'react-bootstrap';
+import { components } from '../../../bedbase-types';
+
+type BedGenomeStats = components['schemas']['RefGenValidReturnModel'];
+
+type Props = {
+ show: boolean;
+ onHide: () => void;
+ genomeStats: BedGenomeStats;
+};
+
+export const RefGenomeModal = (props: Props) => {
+ const { show, onHide, genomeStats } = props;
+
+ console.log(genomeStats?.compared_genome)
+ return (
+ onHide()}
+ size="lg"
+ aria-labelledby="contained-modal-title-vcenter"
+ centered
+ >
+ Reference Genome Compatibility
+
+
+
+
+
+
+ Genome |
+ Compatibility Ranking (1 is best) |
+
+
+
+ {genomeStats?.compared_genome
+ ?.sort((a, b) => a.tier_ranking - b.tier_ranking)
+ .map(item => (
+
+ {item.compared_genome} |
+ {item.tier_ranking} |
+
+ ))}
+
+
+
+
+
+
+ );
+};
diff --git a/ui/src/components/search/bed2bed/b2b-search-results-table.tsx b/ui/src/components/search/bed2bed/b2b-search-results-table.tsx
index e5802e5..9e1be03 100644
--- a/ui/src/components/search/bed2bed/b2b-search-results-table.tsx
+++ b/ui/src/components/search/bed2bed/b2b-search-results-table.tsx
@@ -130,8 +130,8 @@ export const Bed2BedSearchResultsTable = (props: Props) => {
diff --git a/ui/src/components/search/text2bed/t2b-search-results-table.tsx b/ui/src/components/search/text2bed/t2b-search-results-table.tsx
index a19a5f4..07181f2 100644
--- a/ui/src/components/search/text2bed/t2b-search-results-table.tsx
+++ b/ui/src/components/search/text2bed/t2b-search-results-table.tsx
@@ -49,6 +49,8 @@ export const Text2BedSearchResultsTable = (props: Props) => {
}
};
+ console.log(results.results)
+
return (
@@ -122,8 +124,8 @@ export const Text2BedSearchResultsTable = (props: Props) => {
|
diff --git a/ui/src/pages/bed-splash.tsx b/ui/src/pages/bed-splash.tsx
index db18767..c240722 100644
--- a/ui/src/pages/bed-splash.tsx
+++ b/ui/src/pages/bed-splash.tsx
@@ -1,5 +1,6 @@
import { useParams } from 'react-router-dom';
import { useBedMetadata } from '../queries/useBedMetadata';
+import { useBedGenomeStats } from '../queries/useBedGenomeStats';
import { Layout } from '../components/layout';
import { Col, Row } from 'react-bootstrap';
import { BedSplashHeader } from '../components/bed-splash-components/header';
@@ -34,6 +35,13 @@ export const BedSplash = () => {
full: true,
});
+ const {
+ data: genomeStats,
+ } = useBedGenomeStats({
+ md5: bedId,
+ autoRun: true,
+ });
+
const { data: neighbours } = useBedNeighbours({
md5: bedId,
limit: 10,
@@ -131,7 +139,7 @@ export const BedSplash = () => {
- {metadata !== undefined ? : null}
+ {metadata !== undefined && genomeStats !== undefined ? : null}
diff --git a/ui/src/queries/useBedGenomeStats.ts b/ui/src/queries/useBedGenomeStats.ts
new file mode 100644
index 0000000..18dc3c8
--- /dev/null
+++ b/ui/src/queries/useBedGenomeStats.ts
@@ -0,0 +1,29 @@
+import type { components } from '../../bedbase-types.d.ts';
+import { useQuery } from '@tanstack/react-query';
+import { useBedbaseApi } from '../contexts/api-context';
+
+type BedGenomeStatsResponse = components['schemas']['RefGenValidReturnModel'];
+
+type BedGenomeStatsQuery = {
+ md5?: string;
+ autoRun?: boolean;
+};
+
+export const useBedGenomeStats = (query: BedGenomeStatsQuery) => {
+ const { api } = useBedbaseApi();
+ const { md5, autoRun } = query;
+ let enabled = false;
+ if (autoRun !== undefined && autoRun && md5) {
+ enabled = true;
+ }
+
+ return useQuery({
+ queryKey: ['bed-genome-stats', md5],
+ queryFn: async () => {
+ const { data } = await api.get(`/bed/${md5}/genome-stats`);
+ return data;
+ },
+ enabled: enabled,
+ staleTime: 0,
+ });
+};
From 126cf378950905f564f4c6108eb218782f1f207d Mon Sep 17 00:00:00 2001
From: Sam Park
Date: Wed, 15 Jan 2025 12:56:17 -0500
Subject: [PATCH 2/5] remove console.logs
---
ui/src/components/bed-splash-components/refgenome-modal.tsx | 1 -
ui/src/components/search/text2bed/t2b-search-results-table.tsx | 2 --
2 files changed, 3 deletions(-)
diff --git a/ui/src/components/bed-splash-components/refgenome-modal.tsx b/ui/src/components/bed-splash-components/refgenome-modal.tsx
index bad88e2..6dbe8d7 100644
--- a/ui/src/components/bed-splash-components/refgenome-modal.tsx
+++ b/ui/src/components/bed-splash-components/refgenome-modal.tsx
@@ -12,7 +12,6 @@ type Props = {
export const RefGenomeModal = (props: Props) => {
const { show, onHide, genomeStats } = props;
- console.log(genomeStats?.compared_genome)
return (
{
}
};
- console.log(results.results)
-
return (
From 8b79d92a5739a7924246873e289e38e52b3e40f0 Mon Sep 17 00:00:00 2001
From: Sam Park
Date: Wed, 22 Jan 2025 16:21:42 -0500
Subject: [PATCH 3/5] reference genome modal update
---
.../bed-splash-components/refgenome-modal.tsx | 62 ++++++++++++-------
1 file changed, 40 insertions(+), 22 deletions(-)
diff --git a/ui/src/components/bed-splash-components/refgenome-modal.tsx b/ui/src/components/bed-splash-components/refgenome-modal.tsx
index 6dbe8d7..218b063 100644
--- a/ui/src/components/bed-splash-components/refgenome-modal.tsx
+++ b/ui/src/components/bed-splash-components/refgenome-modal.tsx
@@ -12,6 +12,8 @@ type Props = {
export const RefGenomeModal = (props: Props) => {
const { show, onHide, genomeStats } = props;
+ console.log(genomeStats.compared_genome);
+
return (
{
>
Reference Genome Compatibility
-
-
-
-
-
- Genome |
- Compatibility Ranking (1 is best) |
-
-
-
- {genomeStats?.compared_genome
- ?.sort((a, b) => a.tier_ranking - b.tier_ranking)
- .map(item => (
-
- {item.compared_genome} |
- {item.tier_ranking} |
-
- ))}
-
-
-
-
+
+ Ranking and score breakdown; the closer the compatibility rank is to 1, the more compatible the genome is with the given reference genome.
+
+
+ {genomeStats?.compared_genome?.sort((a, b) => a.tier_ranking - b.tier_ranking)
+ .map(genome => (
+
+
+
{genome.compared_genome}
+
Compatibility Rank: {genome.tier_ranking}
+
+
xs
+
+
+
oobr
+
+
+
sequence fit
+
+
+
+
+ ))}
);
From 10b0321af39bacf2dbb682aca02db6376169705e Mon Sep 17 00:00:00 2001
From: Sam Park
Date: Thu, 23 Jan 2025 17:03:14 -0500
Subject: [PATCH 4/5] modal ui updates
---
.../bed-splash-components/refgenome-modal.tsx | 69 ++++++++++++-------
1 file changed, 45 insertions(+), 24 deletions(-)
diff --git a/ui/src/components/bed-splash-components/refgenome-modal.tsx b/ui/src/components/bed-splash-components/refgenome-modal.tsx
index 218b063..1f450a8 100644
--- a/ui/src/components/bed-splash-components/refgenome-modal.tsx
+++ b/ui/src/components/bed-splash-components/refgenome-modal.tsx
@@ -26,38 +26,59 @@ export const RefGenomeModal = (props: Props) => {
Reference Genome Compatibility
- Ranking and score breakdown; the closer the compatibility rank is to 1, the more compatible the genome is with the given reference genome.
+ Note: Below is a ranking of the compatibility various reference genomes to this BED file (rank 1 is best).
+
+
+
+
Genome
+
xs
+
oobr
+
sequence fit
+
Rank
+
+
+
+
{genomeStats?.compared_genome?.sort((a, b) => a.tier_ranking - b.tier_ranking)
.map(genome => (
-
+
-
{genome.compared_genome}
-
Compatibility Rank: {genome.tier_ranking}
-
xs
-
+
+
+
+
{genome.compared_genome}
-
oobr
-
+
+
30 ? 'text-white' : 'text-dark'}`}>
+ {((genome.xs || 0) * 100).toFixed(2) + '%'}
+
+
+
+
+
+
30 ? 'text-white' : 'text-dark'}`}>
+ {((genome.oobr || 0) * 100).toFixed(2) + '%'}
+
+
+
+
+
+
30 ? 'text-white' : 'text-dark'}`}>
+ {((genome.sequence_fit || 0) * 100).toFixed(2) + '%'}
+
+
+
-
sequence fit
-
-
+
Rank {genome.tier_ranking}
+
+
From 0eaf7f8c45c87038b38090f2f7fe5e92e9c1f6cb Mon Sep 17 00:00:00 2001
From: Sam Park
Date: Tue, 28 Jan 2025 13:16:01 -0500
Subject: [PATCH 5/5] modal ui
---
.../components/bed-splash-components/refgenome-modal.tsx | 8 ++++----
ui/src/custom.scss | 5 +++++
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/ui/src/components/bed-splash-components/refgenome-modal.tsx b/ui/src/components/bed-splash-components/refgenome-modal.tsx
index 1f450a8..2c61e57 100644
--- a/ui/src/components/bed-splash-components/refgenome-modal.tsx
+++ b/ui/src/components/bed-splash-components/refgenome-modal.tsx
@@ -44,7 +44,7 @@ export const RefGenomeModal = (props: Props) => {
{genomeStats?.compared_genome?.sort((a, b) => a.tier_ranking - b.tier_ranking)
.map(genome => (
@@ -55,21 +55,21 @@ export const RefGenomeModal = (props: Props) => {
{genome.compared_genome}
-
+
30 ? 'text-white' : 'text-dark'}`}>
{((genome.xs || 0) * 100).toFixed(2) + '%'}
-
+
30 ? 'text-white' : 'text-dark'}`}>
{((genome.oobr || 0) * 100).toFixed(2) + '%'}
-
+
30 ? 'text-white' : 'text-dark'}`}>
{((genome.sequence_fit || 0) * 100).toFixed(2) + '%'}
diff --git a/ui/src/custom.scss b/ui/src/custom.scss
index 7be2237..d5c409e 100644
--- a/ui/src/custom.scss
+++ b/ui/src/custom.scss
@@ -311,3 +311,8 @@ td {
color: #212529;
background: #e9ecef;
}
+
+.genome-card:hover {
+ border: 1px solid $primary;
+ filter: brightness(98%);
+}