Skip to content

Commit

Permalink
feat: add transcript lookup for genes
Browse files Browse the repository at this point in the history
  • Loading branch information
katiestahl committed Nov 15, 2023
1 parent 047cc77 commit 005823a
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 41 deletions.
59 changes: 33 additions & 26 deletions client/src/components/Utilities/GetCoordinates/GetCoordinates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
makeStyles,
Box,
Link,
InputLabel,
FormControl,
} from "@material-ui/core";
import React, { useEffect, useState } from "react";
import { GeneAutocomplete } from "../../main/shared/GeneAutocomplete/GeneAutocomplete";
Expand Down Expand Up @@ -97,6 +99,7 @@ const GetCoordinates: React.FC = () => {

const [geneTranscripts, setGeneTranscripts] = useState([]);
const [geneTxWarnings, setGeneTxWarnings] = useState<string[]>();
const [selectedTranscript, setSelectedTranscript] = useState("");

const [results, setResults] = useState<GenomicData | null>(null);
const [error, setError] = useState<string>("");
Expand All @@ -122,8 +125,8 @@ const GetCoordinates: React.FC = () => {
!exonEndText;

useEffect(() => {
console.log(inputComplete)
if (inputComplete) {
handleGetTranscripts();
fetchResults();
}
}, [
Expand Down Expand Up @@ -184,16 +187,9 @@ const GetCoordinates: React.FC = () => {
}
};

const handleGetTranscripts = () => {
getTranscriptsForGene(gene).then((transcriptsResponse: GetGeneTranscriptsResponse) => {
if (transcriptsResponse.warnings) {
setGeneTxWarnings(transcriptsResponse.warnings);
setGeneTranscripts([]);
} else {
setGeneTxWarnings([]);
setGeneTranscripts(transcriptsResponse.transcripts);
}
});
const handleTranscriptSelect = (event: any) => {
setSelectedTranscript(event.target.value as string);
setTxAc(event.target.value as string);
};

const fetchResults = () => {
Expand All @@ -207,11 +203,7 @@ const GetCoordinates: React.FC = () => {
exonEndOffset
).then((coordsResponse) => handleResponse(coordsResponse));
} else if (inputType == "genomic_coords") {
getExonCoords(chromosome, start, end, strand, gene).then(
(coordsResponse) => handleResponse(coordsResponse)
);
} else if (inputType == "genomic_coords_tx") {
getExonCoords(chromosome, start, end, strand, "", txAc).then(
getExonCoords(chromosome, start, end, strand, gene, txAc).then(
(coordsResponse) => handleResponse(coordsResponse)
);
}
Expand Down Expand Up @@ -269,7 +261,7 @@ const GetCoordinates: React.FC = () => {
errorText={chromosomeText}
/>
<Box mt="18px">
<Box className={classes.strand} width="125px">
<Box className={classes.strand}>
<StrandSwitch
setStrand={setStrand}
selectedStrand={strand}
Expand All @@ -296,12 +288,27 @@ const GetCoordinates: React.FC = () => {
setGeneText={setGeneText}
setChromosome={setChromosome}
setStrand={setStrand}
setTranscripts={setGeneTranscripts}
setDefaultTranscript={setSelectedTranscript}
/>
<TranscriptField
fieldValue={txAc}
valueSetter={setTxAc}
errorText={txAcText}
/>
<FormControl>
<InputLabel>Transcript</InputLabel>
<Select
labelId="transcript-select-label"
id="transcript-select"
value={selectedTranscript}
label="Transcript"
onChange={handleTranscriptSelect}
placeholder="Transcript"
style={{minWidth: "150px"}}
>
{geneTranscripts.map((tx, index) => (
<MenuItem key={index} value={tx}>
{tx}
</MenuItem>
))}
</Select>
</FormControl>
</Box>
{genomicCoordinateInfo}
<Box className={classes.fieldsPair}>
Expand Down Expand Up @@ -333,7 +340,7 @@ const GetCoordinates: React.FC = () => {
<Box className={classes.fieldsPair}>
<TextField
margin="dense"
style={{ width: 125 }}
style={{ minWidth: 125 }}
label="Starting Exon"
value={exonStart}
onChange={(event) => setExonStart(event.target.value)}
Expand All @@ -342,7 +349,7 @@ const GetCoordinates: React.FC = () => {
/>
<TextField
margin="dense"
style={{ width: 125 }}
style={{ minWidth: 125 }}
label="Starting Offset"
value={exonStartOffset}
onChange={(event) => setExonStartOffset(event.target.value)}
Expand All @@ -351,7 +358,7 @@ const GetCoordinates: React.FC = () => {
<Box className={classes.fieldsPair}>
<TextField
margin="dense"
style={{ width: 125 }}
style={{ minWidth: 125 }}
label="Ending Exon"
value={exonEnd}
onChange={(event) => setExonEnd(event.target.value)}
Expand All @@ -360,7 +367,7 @@ const GetCoordinates: React.FC = () => {
/>
<TextField
margin="dense"
style={{ width: 125 }}
style={{ minWidth: 125 }}
label="Ending Offset"
value={exonEndOffset}
onChange={(event) => setExonEndOffset(event.target.value)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { TextField, Typography, makeStyles } from "@material-ui/core";
import Autocomplete, {
AutocompleteRenderGroupParams,
} from "@material-ui/lab/Autocomplete";
import { getGeneSuggestions } from "../../../../services/main";
import { SuggestGeneResponse } from "../../../../services/ResponseModels";
import { getGeneSuggestions, getTranscriptsForGene } from "../../../../services/main";
import { GetGeneTranscriptsResponse, SuggestGeneResponse } from "../../../../services/ResponseModels";
import HelpTooltip from "../HelpTooltip/HelpTooltip";
import { useColorTheme } from "../../../../global/contexts/Theme/ColorThemeContext";

Expand Down Expand Up @@ -50,6 +50,8 @@ interface Props {
promptText?: string | undefined;
setChromosome?: CallableFunction;
setStrand?: CallableFunction;
setTranscripts?: CallableFunction;
setDefaultTranscript?: CallableFunction;
}

export const GeneAutocomplete: React.FC<Props> = ({
Expand All @@ -61,6 +63,8 @@ export const GeneAutocomplete: React.FC<Props> = ({
promptText,
setChromosome,
setStrand,
setTranscripts,
setDefaultTranscript,
}) => {
const existingGeneOption = gene
? { value: gene, type: GeneSuggestionType.symbol }
Expand Down Expand Up @@ -95,6 +99,15 @@ export const GeneAutocomplete: React.FC<Props> = ({
if (setStrand) {
setStrand(selection.strand);
}
if (setTranscripts) {
getTranscriptsForGene(selection.value).then((transcriptsResponse: GetGeneTranscriptsResponse) => {
const transcripts = transcriptsResponse.transcripts
setTranscripts(transcripts);
if (setDefaultTranscript) {
setDefaultTranscript(transcripts[0])
}
});
}
};

// Update options
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { makeStyles, TextField, Typography } from "@material-ui/core";
import React, { KeyboardEventHandler } from "react";
import HelpTooltip from "../HelpTooltip/HelpTooltip";

interface Props {
fieldValue: string;
valueSetter: CallableFunction;
errorText: string;
}

const TranscriptDropdown: React.FC<Props> = ({
fieldValue,
valueSetter,
errorText,
}) => {
const useStyles = makeStyles(() => ({
textField: {
},
}));
const classes = useStyles();

return (
<></>
);
};

export default TranscriptDropdown;
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ interface Props {
fieldValue: string;
valueSetter: CallableFunction;
errorText: string;
keyHandler: KeyboardEventHandler<HTMLDivElement> | undefined;
keyHandler?: KeyboardEventHandler<HTMLDivElement> | undefined;
width?: number | undefined;
}

Expand Down
16 changes: 6 additions & 10 deletions server/curfu/routers/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,12 @@ async def get_transcripts_for_gene(request: Request, gene: str) -> Dict:
"""
normalized = request.app.state.fusor.gene_normalizer.normalize(gene)
symbol = normalized.gene_descriptor.label
print(symbol)
print(request.app.state.fusor.cool_seq_tool.uta_db)
transcripts = await request.app.state.fusor.cool_seq_tool.uta_db.get_transcripts(symbol)
transcripts_dict = transcripts.to_dict()
tx_for_gene = transcripts_dict["tx_ac"]
print(transcripts.glimpse())
transcripts = await request.app.state.fusor.cool_seq_tool.uta_db.get_transcripts(gene=symbol)
tx_for_gene = list(transcripts.rows_by_key("tx_ac"))
if transcripts.is_empty():
return {"warnings": [f"No matching transcripts: {gene}"], "transcripts": []}
else:
return {"transcripts": transcripts}
return {"transcripts": tx_for_gene}

@router.get(
"/api/utilities/get_genomic",
Expand Down Expand Up @@ -133,7 +129,7 @@ async def get_genome_coords(
if exon_end is not None and exon_end_offset is None:
exon_end_offset = 0

response = await request.app.state.fusor.cool_seq_tool.transcript_to_genomic_coordinates( # noqa: E501
response = await request.app.state.fusor.cool_seq_tool.ex_g_coords_mapper.transcript_to_genomic_coordinates( # noqa: E501
gene=gene,
transcript=transcript,
exon_start=exon_start,
Expand Down Expand Up @@ -281,7 +277,7 @@ async def get_sequence(
"""
_, path = tempfile.mkstemp(suffix=".fasta")
try:
request.app.state.fusor.cool_seq_tool.get_fasta_file(sequence_id, Path(path))
request.app.state.fusor.cool_seq_tool.seqrepo_access.get_fasta_file(sequence_id, Path(path))
except KeyError:
resp = request.app.state.fusor.cool_seq_tool.seqrepo_access.translate_identifier( # noqa: E501
sequence_id, "refseq"
Expand All @@ -293,7 +289,7 @@ async def get_sequence(
else:
try:
new_seq_id = resp[0][0].split(":")[1]
request.app.state.fusor.cool_seq_tool.get_fasta_file(
request.app.state.fusor.cool_seq_tool.seqrepo_access.get_fasta_file(
new_seq_id, Path(path)
)
except KeyError:
Expand Down
4 changes: 2 additions & 2 deletions server/curfu/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,12 +251,12 @@ class ManeGeneTranscript(BaseModel):
class GetTranscriptsResponse(Response):
"""Response model for MANE transcript retrieval endpoint."""

transcripts: Optional[List[ManeGeneTranscript]]
transcripts: Optional[List[ManeGeneTranscript]] = None

class GetGeneTranscriptsResponse(Response):
"""Response model for MANE transcript retrieval endpoint."""

transcripts: Optional[Dict]
transcripts: Optional[List[str]] = None


class ServiceInfoResponse(Response):
Expand Down

0 comments on commit 005823a

Please sign in to comment.