<file-match-pattern match-pattern="src/.*.java" include-pattern="true"/>
<file-match-pattern match-pattern="resources/.*.properties" include-pattern="true"/>
</fileset>
- <filter name="NonSrcDirs" enabled="false"/>
</fileset-config>
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+import jalview.analysis.scoremodels.ScoreModels
+import jalview.analysis.scoremodels.SimilarityParams
+
+// generate matrix for current selection using standard Jalview PID
+
+printSimilarityMatrix(true,true,SimilarityParams.Jalview)
+
+/**
+ * this function prints a sequence similarity matrix in PHYLIP format.
+ * printSimilarityMatrix(selected-only, include-ids, pidMethod)
+ *
+ * Allowed values for pidMethod:
+ *
+ * Jalview's Comparison.PID method includes matching gaps
+ * and counts over the length of the shorter gapped sequence
+ * SimilarityParams.Jalview;
+ *
+ * 'SeqSpace' mode PCA calculation does not count matching
+ * gaps but uses longest gapped sequence length
+ * SimilarityParams.SeqSpace;
+ *
+ * PID calcs from the Raghava-Barton paper
+ * SimilarityParams.PID1: ignores gap-gap, does not score gap-residue,
+ * includes gap-residue in lengths, matches on longer of two sequences.
+ *
+ * SimilarityParams.PID2: ignores gap-gap,ignores gap-residue,
+ * matches on longer of two sequences
+ *
+ * SimilarityParams.PID3: ignores gap-gap,ignores gap-residue,
+ * matches on shorter of sequences only
+ *
+ * SimilarityParams.PID4: ignores gap-gap,does not score gap-residue,
+ * includes gap-residue in lengths,matches on shorter of sequences only.
+ */
+
+void printSimilarityMatrix(boolean selview=false, boolean includeids=true, SimilarityParams pidMethod) {
+
+ def currentAlignFrame = jalview.bin.Jalview.getCurrentAlignFrame()
+
+ jalview.gui.AlignViewport av = currentAlignFrame.getCurrentView()
+
+ jalview.datamodel.AlignmentView seqStrings = av.getAlignmentView(selview)
+
+ if (!selview || av.getSelectionGroup()==null) {
+ start = 0
+ end = av.getAlignment().getWidth()
+ seqs = av.getAlignment().getSequencesArray()
+ } else {
+ start = av.getSelectionGroup().getStartRes()
+ end = av.getSelectionGroup().getEndRes() + 1
+ seqs = av.getSelectionGroup().getSequencesInOrder(av.getAlignment())
+ }
+
+ distanceCalc = ScoreModels.getInstance().getScoreModel("PID",
+ (jalview.api.AlignmentViewPanel) currentAlignFrame.alignPanel)
+
+ def distance=distanceCalc.findSimilarities(
+ seqStrings.getSequenceStrings(jalview.util.Comparison.GAP_DASH),pidMethod)
+
+ // output the PHYLIP Matrix
+
+ print distance.width()+" "+distance.height()+"\n"
+
+ p = 0
+
+ for (v in 1..distance.height()) {
+
+ if (includeids) {
+ print seqs[p++].getDisplayId(false)+" "
+ }
+
+ for (r in 1..distance.width()) {
+ print distance.getValue(v-1,r-1)+" "
+ }
+
+ print "\n"
+ }
+}
\ No newline at end of file
429 rate limit request hander
</li>
<li>
- <!-- JAL-2777 -->Structure views don't get updated unless
+ <!-- JAL-2773 -->Structure views don't get updated unless
their colours have changed
</li>
</ul>
+ <ul><li>Example groovy script for generating a matrix of percent identity scores for current alignment.</li></ul>
</td>
<td><div align="left">
<em></em>
<ul>
+ <li><!-- JAL-2777 -->Structures with whitespace chainCode cannot be viewed in Chimera</li>
<li><!-- JAL-2728 -->Protein annotation panel too high in CDS/Protein view
</li>
<li><!-- JAL-2757 -->Can't edit the query after the server error warning icon is shown in Uniprot and PDB Free Text Search Dialogs
</li>
+ <li><!-- JAL-2253 -->Slow EnsemblGenome ID lookup</li>
+ <li><!-- JAL-2682 -->Race condition when parsing sequence ID strings in parallel</li>
+ <li><!-- JAL-2739 -->Hidden column marker in last column not rendered when switching back from Wrapped to normal view</li>
+ <li><!-- JAL-2768 -->Annotation display corrupted when scrolling right in unwapped alignment view</li>
</ul>
</td>
</tr>
public void splitInsertionCode(String residue)
{
// OK, split the index into number and insertion code
+ // JBPNote - m.matches() can be true even if there is no resnum - this can
+ // cause NumberFormatExceptions below
Pattern p = Pattern.compile("(\\d*)([A-Z]?)");
Matcher m = p.matcher(residue);
if (m.matches())
import java.util.ListIterator;
import java.util.Vector;
-import com.stevesoft.pat.Regex;
-
import fr.orsay.lri.varna.models.rna.RNA;
/**
*/
public class Sequence extends ASequence implements SequenceI
{
- private static final Regex limitrx = new Regex(
- "[/][0-9]{1,}[-][0-9]{1,}$");
-
- private static final Regex endrx = new Regex("[0-9]{1,}$");
-
SequenceI datasetSequence;
String name;
checkValidRange();
}
+ /**
+ * If 'name' ends in /i-j, where i >= j > 0 are integers, extracts i and j as
+ * start and end respectively and removes the suffix from the name
+ */
void parseId()
{
if (name == null)
"POSSIBLE IMPLEMENTATION ERROR: null sequence name passed to constructor.");
name = "";
}
- // Does sequence have the /start-end signature?
- if (limitrx.search(name))
+ int slashPos = name.lastIndexOf('/');
+ if (slashPos > -1 && slashPos < name.length() - 1)
{
- name = limitrx.left();
- endrx.search(limitrx.stringMatched());
- setStart(Integer.parseInt(limitrx.stringMatched().substring(1,
- endrx.matchedFrom() - 1)));
- setEnd(Integer.parseInt(endrx.stringMatched()));
+ String suffix = name.substring(slashPos + 1);
+ String[] range = suffix.split("-");
+ if (range.length == 2)
+ {
+ try
+ {
+ int from = Integer.valueOf(range[0]);
+ int to = Integer.valueOf(range[1]);
+ if (from > 0 && to >= from)
+ {
+ name = name.substring(0, slashPos);
+ setStart(from);
+ setEnd(to);
+ checkValidRange();
+ }
+ } catch (NumberFormatException e)
+ {
+ // leave name unchanged if suffix is invalid
+ }
+ }
}
}
+ /**
+ * Ensures that 'end' is not before the end of the sequence, that is,
+ * (end-start+1) is at least as long as the count of ungapped positions. Note
+ * that end is permitted to be beyond the end of the sequence data.
+ */
void checkValidRange()
{
// Note: JAL-774 :
int endRes = 0;
for (int j = 0; j < sequence.length; j++)
{
- if (!jalview.util.Comparison.isGap(sequence[j]))
+ if (!Comparison.isGap(sequence[j]))
{
endRes++;
}
}
/**
- * DOCUMENT ME!
+ * Sets the sequence name. If the name ends in /start-end, then the start-end
+ * values are parsed out and set, and the suffix is removed from the name.
*
- * @param name
- * DOCUMENT ME!
+ * @param theName
*/
@Override
- public void setName(String name)
+ public void setName(String theName)
{
- this.name = name;
+ this.name = theName;
this.parseId();
}
}
/**
- * Converts a query, which may contain one or more gene or transcript
- * identifiers, into a non-redundant list of gene identifiers.
+ * 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
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<String> 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);
}
}
}
}
/**
- * 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<String> 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.
}
@Override
- public boolean isGeneIdentifier(String query)
- {
- return true;
- }
-
- @Override
public String getDbName()
{
return "EnsemblGenomes";
}
+ private String Wrong[];
@Override
public String getTestQuery()
{
public class EnsemblLookup extends EnsemblRestClient
{
+ private static final String OBJECT_TYPE_TRANSLATION = "Translation";
+ private static final String PARENT = "Parent";
+ private static final String OBJECT_TYPE_TRANSCRIPT = "Transcript";
+ private static final String ID = "id";
+ private static final String OBJECT_TYPE_GENE = "Gene";
+ private static final String OBJECT_TYPE = "object_type";
+
/**
* Default constructor (to use rest.ensembl.org)
*/
protected URL getUrl(String identifier)
{
String url = getDomain() + "/lookup/id/" + identifier
- + "?content-type=application/json";
+ + CONTENT_TYPE_JSON;
try
{
return new URL(url);
* @param identifier
* @return
*/
- public String getParent(String identifier)
+ public String getGeneId(String identifier)
{
List<String> ids = Arrays.asList(new String[] { identifier });
}
/**
- * Parses "Parent" from the JSON response and returns the value, or null if
- * not found
+ * Parses the JSON response and returns the gene identifier, or null if not
+ * found. If the returned object_type is Gene, returns the id, if Transcript
+ * returns the Parent. If it is Translation (peptide identifier), then the
+ * Parent is the transcript identifier, so we redo the search with this value.
*
* @param br
* @return
*/
protected String parseResponse(BufferedReader br) throws IOException
{
- String parent = null;
+ String geneId = null;
JSONParser jp = new JSONParser();
try
{
JSONObject val = (JSONObject) jp.parse(br);
- parent = val.get("Parent").toString();
+ String type = val.get(OBJECT_TYPE).toString();
+ if (OBJECT_TYPE_GENE.equalsIgnoreCase(type))
+ {
+ geneId = val.get(ID).toString();
+ }
+ else if (OBJECT_TYPE_TRANSCRIPT.equalsIgnoreCase(type))
+ {
+ geneId = val.get(PARENT).toString();
+ }
+ else if (OBJECT_TYPE_TRANSLATION.equalsIgnoreCase(type))
+ {
+ String transcriptId = val.get(PARENT).toString();
+ try
+ {
+ geneId = getGeneId(transcriptId);
+ } catch (StackOverflowError e)
+ {
+ /*
+ * unlikely data condition error!
+ */
+ System.err
+ .println("** Ensembl lookup "
+ + getUrl(transcriptId).toString()
+ + " looping on Parent!");
+ }
+ }
} catch (ParseException e)
{
// ignore
}
- return parent;
+ return geneId;
}
}
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceFeature;
-import java.util.List;
-
import com.stevesoft.pat.Regex;
/**
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
-import com.stevesoft.pat.Regex;
-
/**
* Base class for Ensembl REST service clients
*
* @see https://github.com/Ensembl/ensembl-rest/wiki/Change-log
* @see http://rest.ensembl.org/info/rest?content-type=application/json
*/
- private static final String LATEST_ENSEMBLGENOMES_REST_VERSION = "5.0";
+ private static final String LATEST_ENSEMBLGENOMES_REST_VERSION = "6.0";
- private static final String LATEST_ENSEMBL_REST_VERSION = "5.0";
+ private static final String LATEST_ENSEMBL_REST_VERSION = "6.1";
private static final String REST_CHANGE_LOG = "https://github.com/Ensembl/ensembl-rest/wiki/Change-log";
private final static long VERSION_RETEST_INTERVAL = 1000L * 3600; // 1 hr
- private static final Regex PROTEIN_REGEX = new Regex(
- "(ENS)([A-Z]{3}|)P[0-9]{11}$");
-
- private static final Regex TRANSCRIPT_REGEX = new Regex(
- "(ENS)([A-Z]{3}|)T[0-9]{11}$");
-
- private static final Regex GENE_REGEX = new Regex(
- "(ENS)([A-Z]{3}|)G[0-9]{11}$");
+ protected static final String CONTENT_TYPE_JSON = "?content-type=application/json";
static
{
- domainData = new HashMap<String, EnsemblInfo>();
+ domainData = new HashMap<>();
domainData.put(ENSEMBL_REST,
new EnsemblInfo(ENSEMBL_REST, LATEST_ENSEMBL_REST_VERSION));
domainData.put(ENSEMBL_GENOMES_REST, new EnsemblInfo(
setDomain(d);
}
- /**
- * Answers true if the query matches the regular expression pattern for an
- * Ensembl transcript stable identifier
- *
- * @param query
- * @return
- */
- public boolean isTranscriptIdentifier(String query)
- {
- return query == null ? false : TRANSCRIPT_REGEX.search(query);
- }
-
- /**
- * Answers true if the query matches the regular expression pattern for an
- * Ensembl protein stable identifier
- *
- * @param query
- * @return
- */
- public boolean isProteinIdentifier(String query)
- {
- return query == null ? false : PROTEIN_REGEX.search(query);
- }
-
- /**
- * Answers true if the query matches the regular expression pattern for an
- * Ensembl gene stable identifier
- *
- * @param query
- * @return
- */
- public boolean isGeneIdentifier(String query)
- {
- return query == null ? false : GENE_REGEX.search(query);
- }
-
@Override
public boolean queryInProgress()
{
{
// note this format works for both ensembl and ensemblgenomes
// info/ping.json works for ensembl only (March 2016)
- URL ping = new URL(
- getDomain() + "/info/ping?content-type=application/json");
+ URL ping = new URL(getDomain() + "/info/ping" + CONTENT_TYPE_JSON);
/*
* expect {"ping":1} if ok
br = getHttpResponse(ping, null, 2 * 1000);
if (br == null)
{
+ // error reponse status
return false;
}
JSONParser jp = new JSONParser();
URL url = null;
try
{
- url = new URL(
- getDomain() + "/info/rest?content-type=application/json");
+ url = new URL(getDomain() + "/info/rest" + CONTENT_TYPE_JSON);
BufferedReader br = getHttpResponse(url, null);
+ if (br == null)
+ {
+ return;
+ }
JSONObject val = (JSONObject) jp.parse(br);
String version = val.get("release").toString();
String majorVersion = version.substring(0, version.indexOf("."));
try
{
- url = new URL(
- getDomain() + "/info/data?content-type=application/json");
+ url = new URL(getDomain() + "/info/data" + CONTENT_TYPE_JSON);
br = getHttpResponse(url, null);
if (br != null)
{
*/
public class EnsemblSymbol extends EnsemblXref
{
+ private static final String GENE = "gene";
+ private static final String TYPE = "type";
+ private static final String ID = "id";
+
/**
* Constructor given the target domain to fetch data from
*
while (rvals.hasNext())
{
JSONObject val = (JSONObject) rvals.next();
- String id = val.get("id").toString();
- if (id != null && isGeneIdentifier(id))
+ String id = val.get(ID).toString();
+ String type = val.get(TYPE).toString();
+ if (id != null && GENE.equals(type))
{
result = id;
break;
return result;
}
- protected URL getUrl(String id, Species species)
+ /**
+ * Constructs the URL for the REST symbol endpoint
+ *
+ * @param id
+ * the accession id (Ensembl or external)
+ * @param species
+ * a species name recognisable by Ensembl
+ * @param type
+ * an optional type to filter the response (gene, transcript,
+ * translation)
+ * @return
+ */
+ protected URL getUrl(String id, Species species, String... type)
{
- String url = getDomain() + "/xrefs/symbol/" + species.toString() + "/"
- + id + "?content-type=application/json";
+ StringBuilder sb = new StringBuilder();
+ sb.append(getDomain()).append("/xrefs/symbol/")
+ .append(species.toString()).append("/").append(id)
+ .append(CONTENT_TYPE_JSON);
+ for (String t : type)
+ {
+ sb.append("&object_type=").append(t);
+ }
try
{
+ String url = sb.toString();
return new URL(url);
} catch (MalformedURLException e)
{
* @param identifier
* @return
*/
- public List<String> getIds(String identifier)
+ public List<String> getGeneIds(String identifier)
{
List<String> result = new ArrayList<String>();
List<String> ids = new ArrayList<String>();
{
for (Species taxon : Species.getModelOrganisms())
{
- URL url = getUrl(query, taxon);
+ URL url = getUrl(query, taxon, GENE);
if (url != null)
{
br = getHttpResponse(url, ids);
if (br != null)
{
String geneId = parseSymbolResponse(br);
- if (geneId != null)
+ System.out.println(url + " returned " + geneId);
+ if (geneId != null && !result.contains(geneId))
{
result.add(geneId);
}
while (rvals.hasNext())
{
JSONObject val = (JSONObject) rvals.next();
- String dbname = val.get("dbname").toString();
- if (GO_GENE_ONTOLOGY.equals(dbname))
- {
- continue;
- }
+ String db = val.get("dbname").toString();
String id = val.get("primary_id").toString();
- if (dbname != null && id != null)
+ if (db != null && id != null
+ && !GO_GENE_ONTOLOGY.equals(db))
{
- dbname = DBRefUtils.getCanonicalName(dbname);
- DBRefEntry dbref = new DBRefEntry(dbname, getXRefVersion(), id);
+ db = DBRefUtils.getCanonicalName(db);
+ DBRefEntry dbref = new DBRefEntry(db, getXRefVersion(), id);
result.add(dbref);
}
}
protected URL getUrl(String identifier)
{
String url = getDomain() + "/xrefs/id/" + identifier
- + "?content-type=application/json&all_levels=1";
+ + CONTENT_TYPE_JSON + "&all_levels=1";
try
{
return new URL(url);
notifyAtomPicked(((Integer) data[2]).intValue(), (String) data[1],
(String) data[0]);
// also highlight in alignment
+ // deliberate fall through
case HOVER:
notifyAtomHovered(((Integer) data[2]).intValue(), (String) data[1],
(String) data[0]);
for (String chain : modelData.keySet())
{
- chain = chain.trim();
+ chain = " ".equals(chain) ? chain : chain.trim();
List<int[]> rangeList = modelData.get(chain);
{
sb.append(start).append("-").append(end);
}
- if (chain.length() > 0)
- {
- sb.append(".").append(chain);
+
+ sb.append(".");
+ if (!" ".equals(chain)) {
+ sb.append(chain);
}
}
}
}
else
{
- int widthInRes = (canvasWidth / av.getCharWidth()) - 1;
+ int widthInRes = (canvasWidth / av.getCharWidth());
int heightInSeq = (getSeqPanel().seqCanvas.getHeight()
- / av.getCharHeight()) - 1;
+ / av.getCharHeight());
vpRanges.setViewportWidth(widthInRes);
vpRanges.setViewportHeight(heightInSeq);
private static final int MIN_WIDTH = 400;
private static final int MIN_HEIGHT = 400;
+
+ /**
+ * when true, constructor is still executing - so ignore UI events
+ */
+ protected volatile boolean inConstruction = true;
/**
* Constructor
};
});
frame.setLayer(JLayeredPane.PALETTE_LAYER);
+ inConstruction = false;
}
protected void popupSort(final int selectedRow, final String type,
@Override
public void stateChanged(ChangeEvent evt)
{
- fr.setTransparency((100 - transparency.getValue()) / 100f);
- af.alignPanel.paintAlignment(true, true);
+ if (!inConstruction)
+ {
+ fr.setTransparency((100 - transparency.getValue()) / 100f);
+ af.alignPanel.paintAlignment(true,true);
+ }
}
});
return null;
}
- if (Comparison.isGap(seq.getCharAt(column)))
+ // column is 'base 1' but getCharAt is an array index (ie from 0)
+ if (Comparison.isGap(seq.getCharAt(column - 1)))
{
/*
* returning null allows the colour scheme to provide gap colour
found = sq.findFeatures(10, 11);
assertEquals(0, found.size());
}
+
+ @Test(groups = { "Functional" })
+ public void testSetName()
+ {
+ SequenceI sq = new Sequence("test", "-ABC---DE-F--");
+ assertEquals("test", sq.getName());
+ assertEquals(1, sq.getStart());
+ assertEquals(6, sq.getEnd());
+
+ sq.setName("testing");
+ assertEquals("testing", sq.getName());
+
+ sq.setName("test/8-10");
+ assertEquals("test", sq.getName());
+ assertEquals(8, sq.getStart());
+ assertEquals(13, sq.getEnd()); // note end is recomputed
+
+ sq.setName("testing/7-99");
+ assertEquals("testing", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd()); // end may be beyond physical end
+
+ sq.setName("/2-3");
+ assertEquals("", sq.getName());
+ assertEquals(2, sq.getStart());
+ assertEquals(7, sq.getEnd());
+
+ sq.setName("test/"); // invalid
+ assertEquals("test/", sq.getName());
+ assertEquals(2, sq.getStart());
+ assertEquals(7, sq.getEnd());
+
+ sq.setName("test/6-13/7-99");
+ assertEquals("test/6-13", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/0-5"); // 0 is invalid - ignored
+ assertEquals("test/0-5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/a-5"); // a is invalid - ignored
+ assertEquals("test/a-5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/6-5"); // start > end is invalid - ignored
+ assertEquals("test/6-5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/5"); // invalid - ignored
+ assertEquals("test/5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/-5"); // invalid - ignored
+ assertEquals("test/-5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/5-"); // invalid - ignored
+ assertEquals("test/5-", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/5-6-7"); // invalid - ignored
+ assertEquals("test/5-6-7", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName(null); // invalid, gets converted to space
+ assertEquals("", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+ }
+
+ @Test(groups = { "Functional" })
+ public void testCheckValidRange()
+ {
+ Sequence sq = new Sequence("test/7-12", "-ABC---DE-F--");
+ assertEquals(7, sq.getStart());
+ assertEquals(12, sq.getEnd());
+
+ /*
+ * checkValidRange ensures end is at least the last residue position
+ */
+ PA.setValue(sq, "end", 2);
+ sq.checkValidRange();
+ assertEquals(12, sq.getEnd());
+
+ /*
+ * end may be beyond the last residue position
+ */
+ PA.setValue(sq, "end", 22);
+ sq.checkValidRange();
+ assertEquals(22, sq.getEnd());
+ }
}
assertEquals(-1, fc.compare("coding_exon", "feature_variant"));
assertEquals(1f, fc.getTransparency());
}
+
+ @Test(groups = "Network")
+ public void testGetGeneIds()
+ {
+ /*
+ * ENSG00000158828 gene id PINK1 human
+ * ENST00000321556 transcript for the same gene - should not be duplicated
+ * P30419 Uniprot identifier for ENSG00000136448
+ * ENST00000592782 transcript for Uniprot gene - should not be duplicated
+ * BRAF - gene name resolvabe (at time of writing) for 6 model species
+ */
+ String ids = "ENSG00000158828 ENST00000321556 P30419 ENST00000592782 BRAF";
+ EnsemblGene testee = new EnsemblGene();
+ List<String> geneIds = testee.getGeneIds(ids);
+ assertEquals(8, geneIds.size());
+ assertTrue(geneIds.contains("ENSG00000158828"));
+ assertTrue(geneIds.contains("ENSG00000136448"));
+ assertTrue(geneIds.contains("ENSG00000157764")); // BRAF human
+ assertTrue(geneIds.contains("ENSMUSG00000002413")); // mouse
+ assertTrue(geneIds.contains("ENSRNOG00000010957")); // rat
+ assertTrue(geneIds.contains("ENSXETG00000004845")); // xenopus
+ assertTrue(geneIds.contains("ENSDARG00000017661")); // zebrafish
+ assertTrue(geneIds.contains("ENSGALG00000012865")); // chicken
+ }
}
}
- @Test(groups = "Functional")
- public void testIsTranscriptIdentifier()
- {
- EnsemblSeqProxy testee = new EnsemblGene();
- assertFalse(testee.isTranscriptIdentifier(null));
- assertFalse(testee.isTranscriptIdentifier(""));
- assertFalse(testee.isTranscriptIdentifier("ENSG00000012345"));
- assertTrue(testee.isTranscriptIdentifier("ENST00000012345"));
- assertTrue(testee.isTranscriptIdentifier("ENSMUST00000012345"));
- assertFalse(testee.isTranscriptIdentifier("enst00000012345"));
- assertFalse(testee.isTranscriptIdentifier("ENST000000123456"));
- assertFalse(testee.isTranscriptIdentifier("ENST0000001234"));
- }
-
- @Test(groups = "Functional")
- public void testIsGeneIdentifier()
- {
- EnsemblSeqProxy testee = new EnsemblGene();
- assertFalse(testee.isGeneIdentifier(null));
- assertFalse(testee.isGeneIdentifier(""));
- assertFalse(testee.isGeneIdentifier("ENST00000012345"));
- assertTrue(testee.isGeneIdentifier("ENSG00000012345"));
- assertTrue(testee.isGeneIdentifier("ENSMUSG00000012345"));
- assertFalse(testee.isGeneIdentifier("ensg00000012345"));
- assertFalse(testee.isGeneIdentifier("ENSG000000123456"));
- assertFalse(testee.isGeneIdentifier("ENSG0000001234"));
- }
-
/**
* Test the method that appends a single allele's reverse complement to a
* string buffer
assertEquals(model.getAtomSpec(), "#0:1-4.B,5-9.C|#1:2-5.A,8.A,5-10.B");
model.addRange(0, 3, 10, "C"); // subsumes 5-9
assertEquals(model.getAtomSpec(), "#0:1-4.B,3-10.C|#1:2-5.A,8.A,5-10.B");
+ model.addRange(5, 25, 35, " "); // empty chain code - e.g. from homology
+ // modelling
+ assertEquals(model.getAtomSpec(),
+ "#0:1-4.B,3-10.C|#1:2-5.A,8.A,5-10.B|#5:25-35.");
+
}
}
package jalview.gui;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
import jalview.bin.Cache;
import jalview.bin.Jalview;
.getAlignment().getWidth() - 1 - 21); // 21 is the number of hidden
// columns
}
+
+ /**
+ * Test that update layout reverts to original (unwrapped) values for endRes
+ * and endSeq when switching from wrapped to unwrapped mode (JAL-2739)
+ */
+ @Test(groups = "Functional")
+ public void TestUpdateLayout_endRes()
+ {
+ // get details of original alignment dimensions
+ ViewportRanges ranges = af.getViewport().getRanges();
+ int endres = ranges.getEndRes();
+
+ // wrap
+ af.alignPanel.getAlignViewport().setWrapAlignment(true);
+ af.alignPanel.updateLayout();
+
+ // endRes changes
+ assertNotEquals(ranges.getEndRes(), endres);
+
+ // unwrap
+ af.alignPanel.getAlignViewport().setWrapAlignment(false);
+ af.alignPanel.updateLayout();
+
+ // endRes and endSeq back to original values
+ assertEquals(ranges.getEndRes(), endres);
+
+ }
}
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
}
@Test(groups = "Functional")
+ public void testFindFeatureAtEnd()
+ {
+ /*
+ * terminal residue feature
+ */
+ seq.addSequenceFeature(new SequenceFeature("PDBRESNUM", "pdb res 1",
+ seq.getEnd(), seq.getEnd(), Float.NaN, "1seq.pdb"));
+ fr.setColour("PDBRESNUM", new FeatureColour(Color.red));
+ fr.featuresAdded();
+ av.setShowSequenceFeatures(true);
+
+ /*
+ * final column should have PDBRESNUM feature, the others not
+ */
+ Color c = finder.findFeatureColour(Color.blue, seq,
+ seq.getLength() - 2);
+ assertNotEquals(c, Color.red);
+ c = finder.findFeatureColour(Color.blue, seq, seq.getLength() - 1);
+ assertEquals(c, Color.red);
+ }
+
+ @Test(groups = "Functional")
public void testFindFeatureColour_graduatedFeatureColour()
{
seq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 2,
<!--
Suppress check of externally sourced code
-->
- <suppress checks="[a-zA-Z0-9]*" files="com[\\/]*"/>
- <suppress checks="[a-zA-Z0-9]*" files="ext[\\/]*"/>
- <suppress checks="[a-zA-Z0-9]*" files="org[\\/]*"/>
- <suppress checks="[a-zA-Z0-9]*" files="uk[\\/]*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="[\\/]com[\\/]github*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="[\\/]com[\\/]stevesoft*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="[\\/]ext[\\/]edu*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="[\\/]ext[\\/]vamsas*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="[\\/]org[\\/]jibble*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="[\\/]uk[\\/]ac*"/>
<!--
ImportControl can only handle one top level package
<subpackage name="datamodel">
<disallow pkg="jalview.gui"/>
<allow pkg="fr.orsay.lri.varna"/>
- <subpackage name="xdb">
- <subpackage name="embl">
- <allow pkg="org.exolab.castor"/>
- </subpackage>
+ <subpackage name="xdb.embl">
+ <allow pkg="org.exolab.castor"/>
</subpackage>
</subpackage>
+ <subpackage name="ext">
+ <subpackage name="ensembl">
+ <allow pkg="javax.ws"/>
+ <allow pkg="org.json"/>
+ </subpackage>
+ <subpackage name="htsjdk">
+ <allow pkg="htsjdk"/>
+ </subpackage>
+ <subpackage name="jmol">
+ <allow pkg="MCview"/>
+ <allow pkg="org.jmol"/>
+ </subpackage>
+ <subpackage name="paradise">
+ <allow pkg="org.apache"/>
+ <allow pkg="org.json"/>
+ </subpackage>
+ <subpackage name="rbvi">
+ <allow pkg="ext.edu.ucsf"/>
+ <allow pkg="javax.servlet"/>
+ </subpackage>
+ <subpackage name="so">
+ <allow pkg="org.biojava"/>
+ </subpackage>
+ <subpackage name="varna">
+ <allow pkg="fr.orsay"/>
+ </subpackage>
+ </subpackage>
+
<subpackage name="fts">
<allow pkg="javax.swing"/>
<allow pkg="javax.ws"/>
</subpackage>
<subpackage name="schemes">
- <allow pkg="org.exolab.castor"/>
+ <allow pkg="org.exolab.castor" class="jalview.schemes.ColourSchemeLoader"/>
</subpackage>
<subpackage name="structure">