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;
{
continue;
}
+
if (geneAlignment.getHeight() == 1)
{
+ // ensure id has 'correct' case for the Ensembl identifier
+ geneId = geneAlignment.getSequenceAt(0).getName();
+
+ findGeneLoci(geneAlignment.getSequenceAt(0), geneId);
+
getTranscripts(geneAlignment, geneId);
}
if (al == null)
}
/**
+ * 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.
cdna.transferFeatures(gene.getFeatures().getPositionalFeatures(),
transcript.getDatasetSequence(), mapping, parentId);
+ mapTranscriptToChromosome(transcript, gene, mapping);
+
/*
* fetch and save cross-references
*/
}
/**
+ * 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<int[]> exons = mapping.getFromRanges();
+ List<int[]> transcriptLoci = new ArrayList<>();
+
+ for (int[] exon : exons)
+ {
+ transcriptLoci.add(geneMapping.locateInTo(exon[0], exon[1]));
+ }
+
+ List<int[]> 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
for (SequenceFeature sf : sfs)
{
String parent = (String) sf.getValue(PARENT);
- if (parentIdentifier.equals(parent))
+ if (parentIdentifier.equalsIgnoreCase(parent))
{
transcriptFeatures.add(sf);
}
{
// NB features as gff use 'ID'; rest services return as 'id'
String id = (String) sf.getValue("ID");
- if ((GENE_PREFIX + accId).equals(id))
+ if ((GENE_PREFIX + accId).equalsIgnoreCase(id))
{
return true;
}
if (isTranscript(type))
{
String parent = (String) sf.getValue(PARENT);
- if (!(GENE_PREFIX + accessionId).equals(parent))
+ if (!(GENE_PREFIX + accessionId).equalsIgnoreCase(parent))
{
return false;
}