From: Jim Procter Date: Wed, 30 Mar 2022 13:14:23 +0000 (+0100) Subject: JAL-3860 prototype for highlight species/assembly/chromosome/position X-Git-Url: http://source.jalview.org/gitweb/?p=jalview.git;a=commitdiff_plain;h=64542e76cacd84f1f03518a8c93404a567a1df0f JAL-3860 prototype for highlight species/assembly/chromosome/position --- diff --git a/src/jalview/datamodel/GenomicAssemblies.java b/src/jalview/datamodel/GenomicAssemblies.java index 13d9a61..b65dcba 100644 --- a/src/jalview/datamodel/GenomicAssemblies.java +++ b/src/jalview/datamodel/GenomicAssemblies.java @@ -173,7 +173,7 @@ public class GenomicAssemblies * assemblies
* will most likely fail for species other than human */ - public static MapList mapAssemblyFor(String seqRef, String species, + public static MapList mapAssemblyFor(String localAssembly, String species, MapList map, String chromosome, String vcfAssembly) { List toVcfRanges = new ArrayList<>(); @@ -188,12 +188,12 @@ public class GenomicAssemblies continue; } - int[] newRange = mapReferenceRange(range, chromosome, species, seqRef, + int[] newRange = mapReferenceRange(range, chromosome, species, localAssembly, vcfAssembly); if (newRange == null) { Console.error(String.format("Failed to map %s:%s:%s:%d:%d to %s", - species, chromosome, seqRef, range[0], range[1], + species, chromosome, localAssembly, range[0], range[1], vcfAssembly)); continue; } @@ -207,4 +207,15 @@ public class GenomicAssemblies return new MapList(fromSequenceRanges, toVcfRanges, 1, 1); } + /** + * get a maplist for positions in the given assembly for the given locus + * @param locus + * @param assembly + * @return + */ + public static MapList mapAssemblyFor(GeneLociI locus, String assembly) + { + return mapAssemblyFor(assembly,locus.getSpeciesId(),locus.getMapping(),locus.getChromosomeId(),locus.getAssemblyId()); + } + } diff --git a/src/jalview/rest/API.java b/src/jalview/rest/API.java index 93e7622..2455914 100644 --- a/src/jalview/rest/API.java +++ b/src/jalview/rest/API.java @@ -50,6 +50,7 @@ public class API extends RestHandler addEndpoint(new HighlightSequenceEndpoint(this)); addEndpoint(new SelectSequencesEndpoint(this)); addEndpoint(new GetCrossReferencesEndpoint(this)); + addEndpoint(new HighlightGenomicRangeEndpoint(this)); setPath(MY_PATH); this.registerHandler(); diff --git a/src/jalview/rest/HighlightGenomicRangeEndpoint.java b/src/jalview/rest/HighlightGenomicRangeEndpoint.java new file mode 100644 index 0000000..b0aa435 --- /dev/null +++ b/src/jalview/rest/HighlightGenomicRangeEndpoint.java @@ -0,0 +1,126 @@ +package jalview.rest; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import jalview.api.AlignmentViewPanel; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.DBRefEntry; +import jalview.datamodel.GeneLociI; +import jalview.datamodel.GeneLocus; +import jalview.datamodel.GenomicAssemblies; +import jalview.datamodel.SequenceI; +import jalview.gui.AlignFrame; +import jalview.structure.StructureSelectionManager; +import jalview.util.MapList; + +public class HighlightGenomicRangeEndpoint extends AbstractEndpoint +{ + public HighlightGenomicRangeEndpoint(API api) + { + super(api, path, name, parameters, description); + } + + protected static final String path = "highlightgenome"; + + private static final String name = "Highlight sequence positions for genomic regions"; + + private static final String parameters = "species/assembly/chromosome/"; + + private static final String description = "Highlight positions in sequences mapped to a particular location in a species' genome. assembly can be just the species name if it is not known."; + + public void processEndpoint(HttpServletRequest request, + HttpServletResponse response) + { + if (!checkParameters(request, response, 4)) + { + return; + } + String[] parameters = getEndpointPathParameters(request); + + String species=parameters[0], assembly=parameters[1],chromid=parameters[2],posString=parameters[3]; + + int pos = -1; + try + { + pos = Integer.parseInt(posString); + } catch (NumberFormatException e) + { + returnError(request, response, + "Could not parse postition integer " + posString); + } + + AlignFrame[] alignFrames = getAlignFrames(request, true); + if (alignFrames == null) + { + returnError(request, response, "could not find results"); + return; + } + + Map ssmMap = new HashMap<>(); + + for (int i = 0; i < alignFrames.length; i++) + { + AlignFrame af = alignFrames[i]; + List aps = (List) af + .getAlignPanels(); + + for (AlignmentViewPanel ap : aps) + { + StructureSelectionManager ssm = ap.getStructureSelectionManager(); + AlignmentI al = ap.getAlignment(); + List seqs = (List) al.getSequences(); + for (SequenceI seq : seqs) + { + GeneLociI locus = seq.getGeneLoci(); + if (locus!=null && locus.getSpeciesId().equalsIgnoreCase(species)) + { + if (locus.getAssemblyId() == null || assembly.equals(species) + || locus.getAssemblyId().equals(assembly)) + { + if (locus.getChromosomeId() != null + && locus.getChromosomeId().equalsIgnoreCase(chromid)) + { + MapList mp = locus.getMapping(); + // TODO: find a better way to determine which is the sequence corresponding to the reference locus (ie the ENSG sequence) + if ((mp.getFromHighest()-mp.getFromLowest())==(mp.getToHighest()-mp.getToLowest())) + { + // genomic locus (we hope) + ssmMap.put(seq, ssm); + } + } + } + } + } + } + } + // highlight + for (SequenceI seq : ssmMap.keySet()) + { + StructureSelectionManager ssm = ssmMap.get(seq); + if (ssm == null) + { + continue; + } + GeneLociI locus = seq.getGeneLoci(); + MapList assmap=locus.getMapping(); + + if (assembly!=null && !assembly.equalsIgnoreCase(species) && locus.getAssemblyId()!=null && !locus.getAssemblyId().equalsIgnoreCase(assembly)) + { + assmap = GenomicAssemblies.mapAssemblyFor(locus, assembly); + } + // locate local position(s) mapping to species:assembly:chromosome:pos + int[] mappedPos = assmap.locateInFrom(pos, pos); + if (mappedPos!=null && mappedPos.length>0) + { + // use vamsas sequence so the position in the reference locus is added to the region being highlighted, as well as the mapped sequence + ssm.mouseOverVamsasSequence(seq.getDatasetSequence(), mappedPos[0], null); + } + } + + } +} \ No newline at end of file