diff --git a/src/api/utils.ts b/src/api/utils.ts
index 199cd2e..ad2a20a 100644
--- a/src/api/utils.ts
+++ b/src/api/utils.ts
@@ -7,7 +7,3 @@ export type DjangoRestApiResponse = {
};
results: unknown[];
};
-
-export const getBaseNameFromKey = (key: string) => {
- return key.split('/')[key.split('/').length - 1];
-};
diff --git a/src/components/OpenInIgvDialog/index.tsx b/src/components/OpenInIgvDialog/index.tsx
index 9015b24..ce4ee19 100644
--- a/src/components/OpenInIgvDialog/index.tsx
+++ b/src/components/OpenInIgvDialog/index.tsx
@@ -9,6 +9,8 @@ import { constructGDSUrl } from '../../api/gds';
import { useToastContext } from '../../providers/ToastProvider';
import CircularLoaderWithText from '../../components/CircularLoaderWithText';
import { post } from 'aws-amplify/api';
+import { useParams } from 'react-router-dom';
+import { SubjectApiRes, usePortalSubjectDataAPI } from '../../api/subject';
type OpenIGVDesktopDialogType = {
handleClose: () => void;
@@ -19,15 +21,32 @@ type OpenIGVDesktopDialogType = {
type: 's3' | 'gds';
};
export default function OpenIGVDesktopDialog(props: OpenIGVDesktopDialogType) {
+ const { subjectId } = useParams();
const { toastShow } = useToastContext();
const { id, bucketOrVolume, pathOrKey, type, handleClose, handleNeedRestore } = props;
+ if (!subjectId) return
No subject Id found!
;
+
+ // Pulling data from usePortalSubjectDataAPI (this hook should cache if it was previously called)
+ const {
+ isError: subjectIsError,
+ error: subjectError,
+ data: subjectData,
+ } = usePortalSubjectDataAPI(subjectId);
+
// Query data
const gdsLocalIgvUrl = useQuery(
['gds-local-igv', bucketOrVolume, pathOrKey],
- async () =>
- await constructGDSLocalIgvUrl({ bucketOrVolume: bucketOrVolume, pathOrKey: pathOrKey }),
- { enabled: type == 'gds', retry: false }
+ async () => {
+ const igvName = constructIgvNameParameter({ pathOrKey, subjectData: subjectData! });
+
+ return await constructGDSLocalIgvUrl({
+ bucketOrVolume: bucketOrVolume,
+ pathOrKey: pathOrKey,
+ igvName: igvName,
+ });
+ },
+ { enabled: type == 'gds' && !!subjectData, retry: false }
);
const s3LocalIgvUrl = useQuery(
@@ -39,12 +58,15 @@ export default function OpenIGVDesktopDialog(props: OpenIGVDesktopDialogType) {
handleNeedRestore();
}
+ const igvName = constructIgvNameParameter({ pathOrKey, subjectData: subjectData! });
+
return constructS3LocalIgvUrl({
+ igvName: igvName,
bucketOrVolume: bucketOrVolume,
pathOrKey: pathOrKey,
});
},
- { enabled: type == 's3', retry: false }
+ { enabled: type == 's3' && !!subjectData, retry: false }
);
// IsError handling
@@ -67,7 +89,23 @@ export default function OpenIGVDesktopDialog(props: OpenIGVDesktopDialogType) {
});
handleClose();
}
- }, [s3LocalIgvUrl.isError, s3LocalIgvUrl.error, gdsLocalIgvUrl.isError, gdsLocalIgvUrl.error]);
+ if (subjectError && subjectIsError) {
+ toastShow({
+ severity: 'error',
+ summary: 'Error on retrieving subject data.',
+ detail: `${subjectError}`,
+ sticky: true,
+ });
+ handleClose();
+ }
+ }, [
+ s3LocalIgvUrl.isError,
+ s3LocalIgvUrl.error,
+ gdsLocalIgvUrl.isError,
+ gdsLocalIgvUrl.error,
+ subjectError,
+ subjectIsError,
+ ]);
useEffect(() => {
let localIgvUrl: string;
@@ -139,8 +177,12 @@ export default function OpenIGVDesktopDialog(props: OpenIGVDesktopDialogType) {
);
}
-const constructGDSLocalIgvUrl = async (props: { bucketOrVolume: string; pathOrKey: string }) => {
- const { bucketOrVolume, pathOrKey } = props;
+const constructGDSLocalIgvUrl = async (props: {
+ igvName: string;
+ bucketOrVolume: string;
+ pathOrKey: string;
+}) => {
+ const { bucketOrVolume, pathOrKey, igvName } = props;
let idxFilePath: string;
if (pathOrKey.endsWith('bam')) {
@@ -183,15 +225,79 @@ const constructGDSLocalIgvUrl = async (props: { bucketOrVolume: string; pathOrKe
const idx = encodeURIComponent(idxFilePresignUrl);
const enf = encodeURIComponent(filePresignUrl);
- const name = pathOrKey.split('/').pop() ?? pathOrKey;
- return `http://localhost:60151/load?index=${idx}&file=${enf}&name=${name}`;
+
+ return `http://localhost:60151/load?index=${idx}&file=${enf}&name=${igvName}`;
};
-const constructS3LocalIgvUrl = async (props: { bucketOrVolume: string; pathOrKey: string }) => {
- const { bucketOrVolume, pathOrKey } = props;
+const constructS3LocalIgvUrl = (props: {
+ igvName: string;
+ bucketOrVolume: string;
+ pathOrKey: string;
+}) => {
+ const { bucketOrVolume, pathOrKey, igvName } = props;
- const name = pathOrKey.split('/').pop() ?? pathOrKey;
const file = `s3://${bucketOrVolume + '/' + pathOrKey}`;
- return `http://localhost:60151/load?file=${encodeURIComponent(file)}&name=${name}`;
+ return `http://localhost:60151/load?file=${encodeURIComponent(file)}&name=${igvName}`;
+};
+
+/**
+ *
+ * We wanted to show more info in the name parameter when opening in IGV
+ * Ref: https://umccr.slack.com/archives/CP356DDCH/p1707116441928299?thread_ts=1706583808.733149&cid=CP356DDCH
+ *
+ * For BAM files the desired outcome is to include libraryId, sampleId, type, and filetype
+ * Desired output: SBJ00000_L0000000_PRJ00000_tumor.bam
+ *
+ * Other than BAM
+ * Desired output: SBJ00000_MDX0000.vcf.gz
+ *
+ * To find the match of metadata for the specific key/path will iterate through the lims record
+ * @param props
+ */
+export const constructIgvNameParameter = ({
+ subjectData,
+ pathOrKey,
+}: {
+ pathOrKey: string;
+ subjectData: SubjectApiRes;
+}): string => {
+ const nameArray: string[] = [];
+
+ const filetype = pathOrKey.split('.').pop();
+ // Find sampleId from its filename
+ const filename = pathOrKey.split('/').pop() ?? pathOrKey;
+ const sampleId = filename.split('.').shift()?.split('_').shift() ?? filename;
+
+ // Append subjectId if filename does not contain subjectId
+ if (!filename.startsWith(subjectData.id)) {
+ nameArray.push(subjectData.id);
+ }
+
+ // If it is a `bam` file it will try to figure out the appropriate libraryId
+ if (filetype?.toLocaleLowerCase() == 'bam') {
+ const libraryIdArray = subjectData.lims.reduce((acc, curr) => {
+ const currLibId = curr.library_id;
+ const currSampId = curr.sample_id;
+
+ // do not want value to appear twice at the return array
+ if (acc.includes(currLibId)) {
+ return acc;
+ }
+
+ // find the matching value and push to the array
+ if (currSampId == sampleId) {
+ acc.push(currLibId);
+ }
+
+ return acc;
+ }, [] as Array);
+
+ nameArray.push(...libraryIdArray);
+ }
+
+ // Append filename at the end
+ nameArray.push(filename);
+
+ return nameArray.join('_');
};
diff --git a/src/containers/subjects/AnalysisResultTable/index.tsx b/src/containers/subjects/AnalysisResultTable/index.tsx
index 4a936bc..f7a6ab1 100644
--- a/src/containers/subjects/AnalysisResultTable/index.tsx
+++ b/src/containers/subjects/AnalysisResultTable/index.tsx
@@ -314,7 +314,7 @@ function AnalysisResultS3Table(prop: AnalysisResultS3TableProps) {
type Props = { subjectId: string };
-function AnalysisResultsPanel({ subjectId }: Props) {
+function AnalysisResultsTable({ subjectId }: Props) {
const { isFetching, isLoading, data } = usePortalSubjectDataAPI(subjectId);
if (isLoading || isFetching) {
@@ -396,7 +396,7 @@ function AnalysisResultsPanel({ subjectId }: Props) {
return ;
}
-export default AnalysisResultsPanel;
+export default AnalysisResultsTable;
function groupResultsData({
results_s3,
diff --git a/src/containers/subjects/IGV/genomes.ts b/src/containers/subjects/IGV/genomes.ts
index a6913d2..d050ffd 100644
--- a/src/containers/subjects/IGV/genomes.ts
+++ b/src/containers/subjects/IGV/genomes.ts
@@ -1,57 +1,68 @@
+// More info see https://github.com/igvteam/igv.js/wiki/Reference-Genome
+
export const genomes = [
{
id: 'hg38',
name: 'Human (GRCh38/hg38)',
- fastaURL: 'https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg38/hg38.fa',
- indexURL: 'https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg38/hg38.fa.fai',
- cytobandURL: 'https://s3.amazonaws.com/igv.org.genomes/hg38/annotations/cytoBandIdeo.txt.gz',
+ fastaURL: 'https://igv-genepattern-org.s3.amazonaws.com/genomes/seq/hg38/hg38.fa',
+ indexURL: 'https://igv-genepattern-org.s3.amazonaws.com/genomes/seq/hg38/hg38.fa.fai',
+ cytobandURL: 'https://igv-genepattern-org.s3.amazonaws.com/genomes/hg38/cytoBandIdeo.txt.gz',
+ aliasURL: 'https://igv-genepattern-org.s3.amazonaws.com/genomes/hg38/hg38_alias.tab',
+ chromSizesURL: 'https://hgdownload.soe.ucsc.edu/goldenPath/hg38/bigZips/hg38.chrom.sizes',
+ twoBitURL: 'https://hgdownload.soe.ucsc.edu/goldenPath/hg38/bigZips/hg38.2bit',
tracks: [
{
name: 'Refseq Genes',
format: 'refgene',
- url: 'https://s3.amazonaws.com/igv.org.genomes/hg38/ncbiRefGene.txt.gz',
+ url: 'https://hgdownload.soe.ucsc.edu/goldenPath/hg38/database/ncbiRefSeq.txt.gz',
indexed: false,
visibilityWindow: -1,
removable: false,
order: 1000000,
+ infoURL: 'https://www.ncbi.nlm.nih.gov/gene/?term=$$',
},
],
},
{
id: 'hg38_1kg',
name: 'Human (hg38 1kg/GATK)',
- compressedFastaURL:
- 'https://s3.amazonaws.com/igv.org.genomes/hg38/Homo_sapiens_assembly38.fasta.gz',
- fastaURL: 'https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg38/hg38.fa',
- indexURL: 'https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg38/hg38.fa.fai',
+ fastaURL:
+ 'https://1000genomes.s3.amazonaws.com/technical/reference/GRCh38_reference_genome/GRCh38_full_analysis_set_plus_decoy_hla.fa',
+ indexURL:
+ 'https://1000genomes.s3.amazonaws.com/technical/reference/GRCh38_reference_genome/GRCh38_full_analysis_set_plus_decoy_hla.fa.fai',
cytobandURL: 'https://s3.amazonaws.com/igv.org.genomes/hg38/annotations/cytoBandIdeo.txt.gz',
tracks: [
{
name: 'Refseq Genes',
format: 'refgene',
- url: 'https://s3.amazonaws.com/igv.org.genomes/hg38/ncbiRefGene.txt.gz',
+ id: 'hg19_genes',
+ url: 'https://hgdownload.soe.ucsc.edu/goldenPath/hg38/database/ncbiRefSeq.txt.gz',
indexed: false,
visibilityWindow: -1,
removable: false,
order: 1000000,
+ infoURL: 'https://www.ncbi.nlm.nih.gov/gene/?term=$$',
},
],
},
{
id: 'hg19',
- name: 'Human (CRCh37/hg19)',
- fastaURL: 'https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg19/hg19.fasta',
- indexURL: 'https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg19/hg19.fasta.fai',
- cytobandURL: 'https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg19/cytoBand.txt',
+ name: 'Human (GRCh37/hg19)',
+ fastaURL: 'https://igv-genepattern-org.s3.amazonaws.com/genomes/seq/hg19/hg19.fasta',
+ indexURL: 'https://igv-genepattern-org.s3.amazonaws.com/genomes/seq/hg19/hg19.fasta.fai',
+ cytobandURL: 'https://igv-genepattern-org.s3.amazonaws.com/genomes/seq/hg19/cytoBand.txt',
+ aliasURL: 'https://s3.amazonaws.com/igv.org.genomes/hg19/hg19_alias.tab',
tracks: [
{
name: 'Refseq Genes',
format: 'refgene',
- url: 'https://s3.amazonaws.com/igv.org.genomes/hg19/ncbiRefGene.txt.gz',
+ id: 'hg19_genes',
+ url: 'https://hgdownload.soe.ucsc.edu/goldenPath/hg19/database/ncbiRefSeq.txt.gz',
indexed: false,
- visibilityWindow: -1,
removable: false,
order: 1000000,
+ infoURL: 'https://www.ncbi.nlm.nih.gov/gene/?term=$$',
+ visibilityWindow: -1,
},
],
},
diff --git a/src/containers/subjects/IGV/index.tsx b/src/containers/subjects/IGV/index.tsx
index 045158a..df8bbe3 100644
--- a/src/containers/subjects/IGV/index.tsx
+++ b/src/containers/subjects/IGV/index.tsx
@@ -1,13 +1,13 @@
-import React, { useState, useCallback } from 'react';
+import React, { useState, useCallback, useEffect } from 'react';
import { ITrack } from 'igv';
import { useQuery } from 'react-query';
import { ProgressBar } from 'primereact/progressbar';
-
import { Button } from 'primereact/button';
import { Dropdown, DropdownChangeEvent } from 'primereact/dropdown';
import { Toolbar } from 'primereact/toolbar';
+import { Dialog } from 'primereact/dialog';
+
import LoadSubjectDataButton from './LoadSubjectDataButton';
-import { getBaseNameFromKey } from '../../../api/utils';
import { GDSRow } from '../../../api/gds';
import { S3Row } from '../../../api/s3';
import {
@@ -21,6 +21,10 @@ import {
} from './utils';
import LoadCustomTrackDataButton from './LoadCustomTrackDataButton';
import { getJwtToken } from '../../../utils/signer';
+import CircularLoaderWithText from '../../../components/CircularLoaderWithText';
+import { SubjectApiRes, usePortalSubjectDataAPI } from '../../../api/subject';
+import { useToastContext } from '../../../providers/ToastProvider';
+import { constructIgvNameParameter } from '../../../components/OpenInIgvDialog';
const toolbarGenomeList = [
{ label: 'hg38', value: 'hg38' },
@@ -36,6 +40,15 @@ export type LoadSubjectDataType = {
type Props = { subjectId: string };
function IGV({ subjectId }: Props) {
+ const { toastShow } = useToastContext();
+
+ const {
+ isLoading: isSubjectLoading,
+ isError: subjectIsError,
+ error: subjectError,
+ data: subjectData,
+ } = usePortalSubjectDataAPI(subjectId);
+
// IGV init
const igv = useQuery(
['initIGV', subjectId],
@@ -70,14 +83,19 @@ function IGV({ subjectId }: Props) {
if (!igvBrowser) return;
// Find and *remove* necessary current Track Data
- const removalTrackNameList: string[] = createRemovalIgvTrackNameList(
- igvSubjectTrackData,
- newChange
- );
+ const removalTrackNameList: string[] = createRemovalIgvTrackNameList({
+ subjectData: subjectData!,
+ oldTrackData: igvSubjectTrackData,
+ newTrackData: newChange,
+ });
removeIgvLoadTrackFromName({ trackNameList: removalTrackNameList, igvBrowser: igvBrowser });
// Find and *add* necessary current Track Data
- const newIgvTrackList = await createNewIgvTrackList(igvSubjectTrackData, newChange);
+ const newIgvTrackList = await createNewIgvTrackList({
+ subjectData: subjectData!,
+ oldTrackData: igvSubjectTrackData,
+ newTrackData: newChange,
+ });
await addIgvLoadTrackFromITrackList({
iTrackList: newIgvTrackList,
igvBrowser: igvBrowser,
@@ -86,7 +104,7 @@ function IGV({ subjectId }: Props) {
// Save changes to current track data state
setIgvSubjectTrackData(newChange);
},
- [igvBrowser, igvSubjectTrackData]
+ [igvBrowser, igvSubjectTrackData, subjectData]
);
// Custom State and Handler
@@ -95,7 +113,12 @@ function IGV({ subjectId }: Props) {
async (s3Row: RequiredS3RowType) => {
if (!igvBrowser) return;
- const newCustomLoadTrack = convertS3RowToHtsgetIgvTrack(s3Row);
+ const igvName = constructIgvNameParameter({
+ pathOrKey: s3Row.key,
+ subjectData: subjectData!,
+ });
+
+ const newCustomLoadTrack = convertS3RowToHtsgetIgvTrack({ s3Row, igvName });
if (newCustomLoadTrack) {
await addIgvLoadTrackFromITrackList({
iTrackList: [newCustomLoadTrack],
@@ -103,17 +126,24 @@ function IGV({ subjectId }: Props) {
});
}
- const basename = getBaseNameFromKey(s3Row.key);
- setCustomTrackDataNameList((prev) => [...prev, basename]);
+ setCustomTrackDataNameList((prev) => [...prev, igvName]);
},
- [igvBrowser]
+ [igvBrowser, subjectData]
);
const handleCustomIgvGDSTrackDataChange = useCallback(
async (gdsRow: RequiredGDSRowType) => {
if (!igvBrowser) return;
- const newCustomLoadTrack = await convertGdsRowToIgvTrack(gdsRow);
+ const igvName = constructIgvNameParameter({
+ pathOrKey: gdsRow.path,
+ subjectData: subjectData!,
+ });
+
+ const newCustomLoadTrack = await convertGdsRowToIgvTrack({
+ gdsRow,
+ igvName,
+ });
if (newCustomLoadTrack) {
await addIgvLoadTrackFromITrackList({
iTrackList: [newCustomLoadTrack],
@@ -121,19 +151,22 @@ function IGV({ subjectId }: Props) {
});
}
- const basename = getBaseNameFromKey(gdsRow.path);
- setCustomTrackDataNameList((prev) => [...prev, basename]);
+ setCustomTrackDataNameList((prev) => [...prev, igvName]);
},
- [igvBrowser]
+ [igvBrowser, subjectData]
);
// Handle remove IGV trackdata
const handleRemoveAllTrackData = () => {
if (!igvBrowser) return;
- let removalTrackNameList: string[] = createRemovalIgvTrackNameList(igvSubjectTrackData, {
- s3RowList: [],
- gdsRowList: [],
+ let removalTrackNameList: string[] = createRemovalIgvTrackNameList({
+ subjectData: subjectData!,
+ oldTrackData: igvSubjectTrackData,
+ newTrackData: {
+ s3RowList: [],
+ gdsRowList: [],
+ },
});
if (customTrackDataNameList.length) {
@@ -149,6 +182,18 @@ function IGV({ subjectId }: Props) {
});
};
+ // IsError handling
+ useEffect(() => {
+ if (subjectError && subjectIsError) {
+ toastShow({
+ severity: 'error',
+ summary: 'Error on retrieving subject data.',
+ detail: `${subjectError}`,
+ sticky: true,
+ });
+ }
+ }, [subjectError, subjectIsError]);
+
const leftToolbarContents = (
<>
+ {(isSubjectLoading || !subjectData) && (
+
+ )}
-
+
{igv.isLoading && (
{
+const createRemovalIgvTrackNameList = ({
+ subjectData,
+ oldTrackData,
+ newTrackData,
+}: {
+ subjectData: SubjectApiRes;
+ oldTrackData: LoadSubjectDataType;
+ newTrackData: LoadSubjectDataType;
+}): string[] => {
const loadTrackNameList: string[] = [];
// Find in S3
@@ -252,15 +314,26 @@ const createRemovalIgvTrackNameList = (
arrayA: oldTrackData.s3RowList,
arrayB: newTrackData.s3RowList,
}) as unknown as S3Row[];
- for (const s3Row of s3RemovalObjectList) loadTrackNameList.push(getBaseNameFromKey(s3Row.key));
+ for (const s3Row of s3RemovalObjectList) {
+ const name = constructIgvNameParameter({
+ pathOrKey: s3Row.key,
+ subjectData: subjectData!,
+ });
+ loadTrackNameList.push(name);
+ }
// Find in GDS
const gdsRemovalObjectList = diffArrayAlphaAndArrayBetaOnObjData({
arrayA: oldTrackData.gdsRowList,
arrayB: newTrackData.gdsRowList,
}) as unknown as GDSRow[];
- for (const gdsRow of gdsRemovalObjectList)
- loadTrackNameList.push(getBaseNameFromKey(gdsRow.path));
+ for (const gdsRow of gdsRemovalObjectList) {
+ const name = constructIgvNameParameter({
+ pathOrKey: gdsRow.path,
+ subjectData: subjectData!,
+ });
+ loadTrackNameList.push(name);
+ }
return loadTrackNameList;
};
@@ -271,10 +344,15 @@ const createRemovalIgvTrackNameList = (
* @param newTrackData
* @returns
*/
-const createNewIgvTrackList = async (
- oldTrackData: LoadSubjectDataType,
- newTrackData: LoadSubjectDataType
-): Promise => {
+const createNewIgvTrackList = async ({
+ subjectData,
+ oldTrackData,
+ newTrackData,
+}: {
+ subjectData: SubjectApiRes;
+ oldTrackData: LoadSubjectDataType;
+ newTrackData: LoadSubjectDataType;
+}): Promise => {
const newIgvLoadTrackList: ITrack[] = [];
// Find new IGV Track Data for S3
@@ -283,7 +361,12 @@ const createNewIgvTrackList = async (
arrayB: oldTrackData.s3RowList,
}) as unknown as S3Row[];
for (const s3Row of newS3ObjectList) {
- const newS3Itrack = convertS3RowToHtsgetIgvTrack(s3Row);
+ const igvName = constructIgvNameParameter({
+ pathOrKey: s3Row.key,
+ subjectData: subjectData!,
+ });
+
+ const newS3Itrack = convertS3RowToHtsgetIgvTrack({ s3Row, igvName });
if (newS3Itrack != null) newIgvLoadTrackList.push(newS3Itrack);
}
@@ -293,7 +376,12 @@ const createNewIgvTrackList = async (
arrayB: oldTrackData.gdsRowList,
}) as unknown as GDSRow[];
for (const gdsRow of newGdsObjectList) {
- const newGdsTrack = await convertGdsRowToIgvTrack(gdsRow);
+ const igvName = constructIgvNameParameter({
+ pathOrKey: gdsRow.path,
+ subjectData: subjectData!,
+ });
+
+ const newGdsTrack = await convertGdsRowToIgvTrack({ gdsRow, igvName });
if (newGdsTrack != null) newIgvLoadTrackList.push(newGdsTrack);
}
return newIgvLoadTrackList;
diff --git a/src/containers/subjects/IGV/utils.ts b/src/containers/subjects/IGV/utils.ts
index d917f8b..54476cb 100644
--- a/src/containers/subjects/IGV/utils.ts
+++ b/src/containers/subjects/IGV/utils.ts
@@ -1,9 +1,11 @@
import config from '../../../config';
-import { getBaseNameFromKey } from '../../../api/utils';
-import { constructGDSUrl } from '../../../api/gds';
+import { GDSRow, constructGDSUrl } from '../../../api/gds';
import igv, { IGVBrowser, ITrack } from 'igv';
import { post } from 'aws-amplify/api';
+import { constructIgvNameParameter } from '../../../components/OpenInIgvDialog';
import genomes from './genomes';
+import { SubjectApiRes } from '../../../api/subject';
+import { S3Row } from '../../../api/s3';
/**
* IGV OPERATIONS
@@ -23,13 +25,15 @@ export const initIgv = async (props: { initRefGenome: string; oAuthToken: string
return igvBrowser;
};
-export type RequiredS3RowType = {
- key: string;
- bucket: string;
-} & Record;
-export const convertS3RowToHtsgetIgvTrack = (s3row: RequiredS3RowType): ITrack => {
- const { key, bucket } = s3row;
- const baseName = getBaseNameFromKey(key);
+export type RequiredS3RowType = Pick;
+export const convertS3RowToHtsgetIgvTrack = ({
+ s3Row,
+ igvName,
+}: {
+ s3Row: RequiredS3RowType;
+ igvName: string;
+}): ITrack => {
+ const { key, bucket } = s3Row;
// we have umccr specific rule about how our htsget ids are constructed
const id = bucket + '/' + key;
@@ -42,7 +46,7 @@ export const convertS3RowToHtsgetIgvTrack = (s3row: RequiredS3RowType): ITrack =
url: config.htsget.URL,
endpoint: config.htsget.ENDPOINT_READS,
id: id.replace('.bam', ''),
- name: baseName,
+ name: igvName,
removable: false,
};
} else if (key.endsWith('vcf') || key.endsWith('vcf.gz')) {
@@ -53,7 +57,7 @@ export const convertS3RowToHtsgetIgvTrack = (s3row: RequiredS3RowType): ITrack =
url: config.htsget.URL,
endpoint: config.htsget.ENDPOINT_VARIANTS,
id: id.replace('.vcf', '').replace('.gz', ''),
- name: baseName,
+ name: igvName,
removable: false,
visibilityWindow: -1,
};
@@ -62,13 +66,14 @@ export const convertS3RowToHtsgetIgvTrack = (s3row: RequiredS3RowType): ITrack =
}
};
-export type RequiredGDSRowType = {
- volume_name: string;
- path: string;
-} & Record;
-export const convertGdsRowToIgvTrack = async (
- gdsRow: RequiredGDSRowType
-): Promise => {
+export type RequiredGDSRowType = Pick;
+export const convertGdsRowToIgvTrack = async ({
+ gdsRow,
+ igvName,
+}: {
+ gdsRow: RequiredGDSRowType;
+ igvName: string;
+}): Promise => {
const { volume_name, path } = gdsRow;
// Find gds index path
let idxFilePath: string;
@@ -107,8 +112,6 @@ export const convertGdsRowToIgvTrack = async (
idxFilePresignUrl = presigned_url;
}
}
-
- const baseName = getBaseNameFromKey(path);
if (path.endsWith('vcf') || path.endsWith('vcf.gz')) {
return {
type: 'variant',
@@ -117,7 +120,7 @@ export const convertGdsRowToIgvTrack = async (
url: filePresignUrl,
indexURL: idxFilePresignUrl,
id: fileGdsUrl,
- name: baseName,
+ name: igvName,
removable: false,
visibilityWindow: -1,
};
@@ -129,7 +132,7 @@ export const convertGdsRowToIgvTrack = async (
url: filePresignUrl,
indexURL: idxFilePresignUrl,
id: fileGdsUrl,
- name: baseName,
+ name: igvName,
removable: false,
};
} else if (path.endsWith('cram')) {
@@ -140,7 +143,7 @@ export const convertGdsRowToIgvTrack = async (
url: filePresignUrl,
indexURL: idxFilePresignUrl,
id: fileGdsUrl,
- name: baseName,
+ name: igvName,
removable: false,
};
}
diff --git a/src/pages/subjects/SubjectDataPage/index.tsx b/src/pages/subjects/SubjectDataPage/index.tsx
index 07a91ea..a7eef28 100644
--- a/src/pages/subjects/SubjectDataPage/index.tsx
+++ b/src/pages/subjects/SubjectDataPage/index.tsx
@@ -10,7 +10,7 @@ function SubjectDataPage() {
const { subjectId } = useParams();
if (!subjectId) {
- return No Subject ID Provided
;
+ return No Subject Id Provided
;
}
const chipDataS3: Record[] = PresetDataFactory.buildAnalysisDataS3();