package jalview.ext.ensembl; import jalview.datamodel.AlignmentI; import jalview.datamodel.DBRefSource; import java.io.BufferedReader; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.Iterator; import java.util.List; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; public class EnsemblMap extends EnsemblRestClient { /** * Default constructor (to use rest.ensembl.org) */ public EnsemblMap() { super(); } /** * Constructor given the target domain to fetch data from * * @param */ public EnsemblMap(String domain) { super(domain); } @Override public String getDbName() { return DBRefSource.ENSEMBL; } @Override public AlignmentI getSequenceRecords(String queries) throws Exception { return null; // not used } /** * Constructs a URL of the format * http://rest.ensembl.org/map/human/GRCh38/17:45051610..45109016:1/GRCh37?content-type=application/json * * * @param species * @param chromosome * @param fromRef * @param toRef * @param startPos * @param endPos * @return * @throws MalformedURLException */ protected URL getUrl(String species, String chromosome, String fromRef, String toRef, int startPos, int endPos) throws MalformedURLException { /* * start-end might be reverse strand - present forwards to the service */ boolean forward = startPos <= endPos; int start = forward ? startPos : endPos; int end = forward ? endPos : startPos; String strand = forward ? "1" : "-1"; String url = String.format( "%s/map/%s/%s/%s:%d..%d:%s/%s?content-type=application/json", getDomain(), species, fromRef, chromosome, start, end, strand, toRef); try { return new URL(url); } catch (MalformedURLException e) { return null; } } @Override protected boolean useGetRequest() { return true; } @Override protected String getRequestMimeType(boolean multipleIds) { return "application/json"; } @Override protected String getResponseMimeType() { return "application/json"; } @Override protected URL getUrl(List ids) throws MalformedURLException { return null; // not used } public int[] getMapping(String species, String chromosome, String fromRef, String toRef, int[] queryRange) { URL url = null; BufferedReader br = null; try { url = getUrl(species, chromosome, fromRef, toRef, queryRange[0], queryRange[1]); // System.out.println("Calling " + url); br = getHttpResponse(url, null); return (parseResponse(br)); } catch (Throwable t) { System.out.println("Error calling " + url + ": " + t.getMessage()); return null; } } /** * Parses the JSON response from the /map REST service. The format is (with * some fields omitted) * *
   *  {"mappings": 
   *    [{
   *       "original": {"end":45109016,"start":45051610},
   *       "mapped"  : {"end":43186384,"start":43128978} 
   *  }] }
   * 
* * @param br * @return */ protected int[] parseResponse(BufferedReader br) { int[] result = null; JSONParser jp = new JSONParser(); try { JSONObject parsed = (JSONObject) jp.parse(br); JSONArray mappings = (JSONArray) parsed.get("mappings"); Iterator rvals = mappings.iterator(); while (rvals.hasNext()) { // todo check for "mapped" JSONObject val = (JSONObject) rvals.next(); JSONObject mapped = (JSONObject) val.get("mapped"); int start = Integer.parseInt(mapped.get("start").toString()); int end = Integer.parseInt(mapped.get("end").toString()); String strand = mapped.get("strand").toString(); if ("1".equals(strand)) { result = new int[] { start, end }; } else { result = new int[] { end, start }; } } } catch (IOException | ParseException | NumberFormatException e) { // ignore } return result; } }