X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fext%2Fensembl%2FEnsemblGene.java;h=afff4c2630609be55291630e560b3c23e0bdbf05;hb=a57976ba40e1abe6d7c1940386e1a25419ef9c9d;hp=2d4d61abfa27a14aa4f5cb44946c3242b85e98dd;hpb=19fe93b91d4c50834b1a7101da2b1c240c55ae84;p=jalview.git diff --git a/src/jalview/ext/ensembl/EnsemblGene.java b/src/jalview/ext/ensembl/EnsemblGene.java index 2d4d61a..afff4c2 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; @@ -110,7 +112,8 @@ public class EnsemblGene extends EnsemblSeqProxy *
  • resolves an external identifier by looking up xref-ed gene ids
  • *
  • fetches the gene sequence
  • *
  • fetches features on the sequence
  • - *
  • identifies "transcript" features whose Parent is the requested gene
  • + *
  • identifies "transcript" features whose Parent is the requested + * gene
  • *
  • fetches the transcript sequence for each transcript
  • *
  • makes a mapping from the gene to each transcript
  • *
  • copies features from gene to transcript sequences
  • @@ -143,6 +146,9 @@ public class EnsemblGene extends EnsemblSeqProxy { continue; } + + parseChromosomeLocations(geneAlignment); + if (geneAlignment.getHeight() == 1) { getTranscripts(geneAlignment, geneId); @@ -160,8 +166,48 @@ 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. + * Parses and saves fields of an Ensembl-style description e.g. + * chromosome:GRCh38:17:45051610:45109016:1 + * + * @param alignment + */ + private void parseChromosomeLocations(AlignmentI alignment) + { + for (SequenceI seq : alignment.getSequences()) + { + String description = seq.getDescription(); + if (description == null) + { + continue; + } + 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 = ""; // dunno yet! + 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); + } catch (NumberFormatException e) + { + System.err.println("Bad integers in description " + description); + } + } + } + } + + /** + * 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 @@ -172,39 +218,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); } } - - /* - * 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); } } } @@ -213,30 +250,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. @@ -298,8 +311,8 @@ public class EnsemblGene extends EnsemblSeqProxy * the parent gene sequence, with features * @return */ - SequenceI makeTranscript(SequenceFeature transcriptFeature, - AlignmentI al, SequenceI gene) + SequenceI makeTranscript(SequenceFeature transcriptFeature, AlignmentI al, + SequenceI gene) { String accId = getTranscriptId(transcriptFeature); if (accId == null) @@ -348,7 +361,8 @@ public class EnsemblGene extends EnsemblSeqProxy mappedFrom.add(new int[] { sf.getBegin(), sf.getEnd() }); } - Sequence transcript = new Sequence(accId, seqChars, 1, transcriptLength); + Sequence transcript = new Sequence(accId, seqChars, 1, + transcriptLength); /* * Ensembl has gene name as transcript Name @@ -384,6 +398,8 @@ public class EnsemblGene extends EnsemblSeqProxy cdna.transferFeatures(gene.getFeatures().getPositionalFeatures(), transcript.getDatasetSequence(), mapping, parentId); + mapTranscriptToChromosome(transcript, gene, mapping); + /* * fetch and save cross-references */ @@ -398,6 +414,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 @@ -411,6 +463,12 @@ public class EnsemblGene extends EnsemblSeqProxy /** * Returns a list of the transcript features on the sequence whose Parent is * the gene for the accession id. + *

    + * Transcript features are those of type "transcript", or any of its sub-types + * in the Sequence Ontology e.g. "mRNA", "processed_transcript". We also + * include "NMD_transcript_variant", because this type behaves like a + * transcript identifier in Ensembl, although strictly speaking it is not in + * the SO. * * @param accId * @param geneSequence @@ -422,19 +480,18 @@ public class EnsemblGene extends EnsemblSeqProxy List transcriptFeatures = new ArrayList(); String parentIdentifier = GENE_PREFIX + accId; - // todo optimise here by transcript type! + List sfs = geneSequence.getFeatures() - .getPositionalFeatures(); + .getFeaturesByOntology(SequenceOntologyI.TRANSCRIPT); + sfs.addAll(geneSequence.getFeatures().getPositionalFeatures( + SequenceOntologyI.NMD_TRANSCRIPT_VARIANT)); for (SequenceFeature sf : sfs) { - if (isTranscript(sf.getType())) + String parent = (String) sf.getValue(PARENT); + if (parentIdentifier.equals(parent)) { - String parent = (String) sf.getValue(PARENT); - if (parentIdentifier.equals(parent)) - { - transcriptFeatures.add(sf); - } + transcriptFeatures.add(sf); } } @@ -551,8 +608,8 @@ public class EnsemblGene extends EnsemblSeqProxy @Override public boolean isFeatureDisplayed(String type) { - return (so.isA(type, SequenceOntologyI.EXON) || so.isA(type, - SequenceOntologyI.SEQUENCE_VARIANT)); + return (so.isA(type, SequenceOntologyI.EXON) + || so.isA(type, SequenceOntologyI.SEQUENCE_VARIANT)); } @Override