X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fext%2Fensembl%2FEnsemblGene.java;h=cdcfa9642c5f3f57e3a4a0ff976b7904fc624955;hb=1a34e43f7fb8e6d4f559026c6f0a207893124c6d;hp=ad013241c136a5478645c24b94fb18073b2aecd4;hpb=b3ad9eb10b8d77634a5dae103fa0d0834e6ffe6a;p=jalview.git diff --git a/src/jalview/ext/ensembl/EnsemblGene.java b/src/jalview/ext/ensembl/EnsemblGene.java index ad01324..cdcfa96 100644 --- a/src/jalview/ext/ensembl/EnsemblGene.java +++ b/src/jalview/ext/ensembl/EnsemblGene.java @@ -23,6 +23,8 @@ package jalview.ext.ensembl; import jalview.api.FeatureColourI; import jalview.api.FeatureSettingsModelI; import jalview.datamodel.AlignmentI; +import jalview.datamodel.DBRefEntry; +import jalview.datamodel.GeneLociI; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; @@ -144,8 +146,10 @@ public class EnsemblGene extends EnsemblSeqProxy { continue; } + if (geneAlignment.getHeight() == 1) { + findGeneLoci(geneAlignment.getSequenceAt(0), geneId); getTranscripts(geneAlignment, geneId); } if (al == null) @@ -161,8 +165,70 @@ public class EnsemblGene extends EnsemblSeqProxy } /** - * Converts a query, which may contain one or more gene or transcript - * identifiers, into a non-redundant list of gene identifiers. + * Calls the /lookup/id REST service, parses the response for gene + * coordinates, and if successful, adds these to the sequence. If this fails, + * fall back on trying to parse the sequence description in case it is in + * Ensembl-gene format e.g. chromosome:GRCh38:17:45051610:45109016:1. + * + * @param seq + * @param geneId + */ + void findGeneLoci(SequenceI seq, String geneId) + { + GeneLociI geneLoci = new EnsemblLookup(getDomain()).getGeneLoci(geneId); + if (geneLoci != null) + { + seq.setGeneLoci(geneLoci.getSpeciesId(), geneLoci.getAssemblyId(), + geneLoci.getChromosomeId(), geneLoci.getMap()); + } + else + { + parseChromosomeLocations(seq); + } + } + + /** + * Parses and saves fields of an Ensembl-style description e.g. + * chromosome:GRCh38:17:45051610:45109016:1 + * + * @param seq + */ + boolean parseChromosomeLocations(SequenceI seq) + { + String description = seq.getDescription(); + if (description == null) + { + return false; + } + String[] tokens = description.split(":"); + if (tokens.length == 6 && tokens[0].startsWith(DBRefEntry.CHROMOSOME)) + { + String ref = tokens[1]; + String chrom = tokens[2]; + try + { + int chStart = Integer.parseInt(tokens[3]); + int chEnd = Integer.parseInt(tokens[4]); + boolean forwardStrand = "1".equals(tokens[5]); + String species = ""; // not known here + int[] from = new int[] { seq.getStart(), seq.getEnd() }; + int[] to = new int[] { forwardStrand ? chStart : chEnd, + forwardStrand ? chEnd : chStart }; + MapList map = new MapList(from, to, 1, 1); + seq.setGeneLoci(species, ref, chrom, map); + return true; + } catch (NumberFormatException e) + { + System.err.println("Bad integers in description " + description); + } + } + return false; + } + + /** + * Converts a query, which may contain one or more gene, transcript, or + * external (to Ensembl) identifiers, into a non-redundant list of gene + * identifiers. * * @param accessions * @return @@ -173,54 +239,30 @@ public class EnsemblGene extends EnsemblSeqProxy for (String acc : accessions.split(getAccessionSeparator())) { - if (isGeneIdentifier(acc)) - { - if (!geneIds.contains(acc)) - { - geneIds.add(acc); - } - } - /* - * if given a transcript id, look up its gene parent + * First try lookup as an Ensembl (gene or transcript) identifier */ - else if (isTranscriptIdentifier(acc)) + String geneId = new EnsemblLookup(getDomain()).getGeneId(acc); + if (geneId != null) { - String geneId = new EnsemblLookup(getDomain()).getParent(acc); - if (geneId != null && !geneIds.contains(geneId)) + if (!geneIds.contains(geneId)) { geneIds.add(geneId); } } - else if (isProteinIdentifier(acc)) - { - String tscriptId = new EnsemblLookup(getDomain()).getParent(acc); - if (tscriptId != null) - { - String geneId = new EnsemblLookup(getDomain()) - .getParent(tscriptId); - - if (geneId != null && !geneIds.contains(geneId)) - { - geneIds.add(geneId); - } - } - // NOTE - acc is lost if it resembles an ENS.+ ID but isn't actually - // resolving to one... e.g. ENSMICP00000009241 - } - /* - * if given a gene or other external name, lookup and fetch - * the corresponding gene for all model organisms - */ else { + /* + * if given a gene or other external name, lookup and fetch + * the corresponding gene for all model organisms + */ List ids = new EnsemblSymbol(getDomain(), getDbSource(), - getDbVersion()).getIds(acc); - for (String geneId : ids) + getDbVersion()).getGeneIds(acc); + for (String id : ids) { - if (!geneIds.contains(geneId)) + if (!geneIds.contains(id)) { - geneIds.add(geneId); + geneIds.add(id); } } } @@ -229,30 +271,6 @@ public class EnsemblGene extends EnsemblSeqProxy } /** - * Attempts to get Ensembl stable identifiers for model organisms for a gene - * name by calling the xrefs symbol REST service to resolve the gene name. - * - * @param query - * @return - */ - protected String getGeneIdentifiersForName(String query) - { - List ids = new EnsemblSymbol(getDomain(), getDbSource(), - getDbVersion()).getIds(query); - if (ids != null) - { - for (String id : ids) - { - if (isGeneIdentifier(id)) - { - return id; - } - } - } - return null; - } - - /** * Constructs all transcripts for the gene, as identified by "transcript" * features whose Parent is the requested gene. The coding transcript * sequences (i.e. with introns omitted) are added to the alignment. @@ -401,6 +419,8 @@ public class EnsemblGene extends EnsemblSeqProxy cdna.transferFeatures(gene.getFeatures().getPositionalFeatures(), transcript.getDatasetSequence(), mapping, parentId); + mapTranscriptToChromosome(transcript, gene, mapping); + /* * fetch and save cross-references */ @@ -415,6 +435,42 @@ public class EnsemblGene extends EnsemblSeqProxy } /** + * If the gene has a mapping to chromosome coordinates, derive the transcript + * chromosome regions and save on the transcript sequence + * + * @param transcript + * @param gene + * @param mapping + * the mapping from gene to transcript positions + */ + protected void mapTranscriptToChromosome(SequenceI transcript, + SequenceI gene, MapList mapping) + { + GeneLociI loci = gene.getGeneLoci(); + if (loci == null) + { + return; + } + + MapList geneMapping = loci.getMap(); + + List exons = mapping.getFromRanges(); + List transcriptLoci = new ArrayList<>(); + + for (int[] exon : exons) + { + transcriptLoci.add(geneMapping.locateInTo(exon[0], exon[1])); + } + + List transcriptRange = Arrays.asList(new int[] { + transcript.getStart(), transcript.getEnd() }); + MapList mapList = new MapList(transcriptRange, transcriptLoci, 1, 1); + + transcript.setGeneLoci(loci.getSpeciesId(), loci.getAssemblyId(), + loci.getChromosomeId(), mapList); + } + + /** * Returns the 'transcript_id' property of the sequence feature (or null) * * @param feature