* The Jalview Authors are detailed in the 'AUTHORS' file.
-->
<head>
-<title>Amino Acid Properties</title>
+<style>
+body {
+ font-size: 100%;
+}
+table {
+ border: solid;
+ border-collapse: separate;
+}
+th, td {
+ border-style:none;
+ font-family: "Courier New", Courier, mono;
+ font-size: large;
+}
+</style><title>Amino Acid Properties</title>
</head>
<body>
<div align="center">
<h1>Amino Acid Properties</h1>
<img src="properties.gif"> <br>
- <table width="295" border="1" cellspacing="0" cellpadding="0">
- <tr>
- <td width="291"><pre>
- <font size="4" face="Courier New, Courier, mono"><strong>ILVCAGMFYWHKREQDNSTPBZX-</strong>
-XXXXXXXXXXX·······X···XX Hydrophobic
-········XXXXXXXXXX·XXXXX Polar
-··XXXX·········XXXXX··XX Small
-···················X··XX Proline
-····XX···········X····XX Tiny
-XXX···················XX Aliphatic
-·······XXXX···········XX Aromatic
-··········XXX·········XX Positive
-·············X·X······XX Negative
-··········XXXX·X······XX Charged</font>
- </pre></td>
- </tr>
+ <table>
+ <tr><th>ILVCA</th><th>GMFYW</th><th>HKREQ</th><th>DNSTP</th><th>BZX-</th><th></th></tr>
+ <tr><td>XXXXX</td><td>XXXXX</td><td>XX···</td><td>···X·</td><td>··XX</td><td>Hydrophobic</td></tr>
+<tr><td>·····</td><td>···XX</td><td>XXXXX</td><td>XXXX·</td><td>XXXX</td><td>Polar</td></tr>
+<tr><td>··XXX</td><td>X····</td><td>·····</td><td>XXXXX</td><td>··XX</td><td>Small</td></tr>
+<tr><td>·····</td><td>·····</td><td>·····</td><td>····X</td><td>··XX</td><td>Proline</td></tr>
+<tr><td>····X</td><td>X····</td><td>·····</td><td>··X··</td><td>··XX</td><td>Tiny</td></tr>
+<tr><td>XXX··</td><td>·····</td><td>·····</td><td>·····</td><td>··XX</td><td>Aliphatic</td></tr>
+<tr><td>·····</td><td>··XXX</td><td>X····</td><td>·····</td><td>··XX</td><td>Aromatic</td></tr>
+<tr><td>·····</td><td>·····</td><td>XXX··</td><td>·····</td><td>··XX</td><td>Positive</td></tr>
+<tr><td>·····</td><td>·····</td><td>···X·</td><td>X····</td><td>··XX</td><td>Negative</td></tr>
+<tr><td>·····</td><td>·····</td><td>XXXX·</td><td>X····</td><td>··XX</td><td>Charged</td></tr>
</table>
+ </font>
</div>
<p>
<br> From Livingstone, C. D. and Barton, G. J. (1993), <br>
and the desktop application are able to open URLs as 'popups' in
your web browser. <br> Double-clicking on the ID of a sequence
will open the first URL that can be generated from its sequence ID.
- This is often the SRS site, but you can easily configure your own <a
+ This is by default the EMBL-EBI site, but you can easily configure your own <a
href="#urllinks">sequence URL links</a>.
</p>
<p>
<p>
<strong><a name="urllinks">Configuring URL Links</a></strong> <br>URL
links are defined in the "Connections" tab of the <a
- href="../features/preferences.html">Jalview desktop
- preferences</a>, or specified as <a
- href="http://www.jalview.org/examples/appletParameters.html#parameters">applet
- parameters</a>. <br> By default the item "SRS" is added
+ href="../features/preferences.html">Jalview desktop
+ preferences</a>, or specified as <a
+ href="http://www.jalview.org/examples/appletParameters.html#parameters">applet
+ parameters</a>. <br> By default the item "EMBL-EBI Search" is added
to this link menu. This link will show a web page in your default
browser with the selected sequence id as part of the URL.<br>
In the preferences dialog box, click <strong>new</strong> to add a
to remove it.<br> You can name the link, this will be displayed
on a new menu item under the "Link" menu when you right
click on a sequence id. <br> The URL string must contain a
- token that can be replaced with a sequence ID. The simplest token is
+ token that can be replaced with a sequence ID or DB accession ID. The simplest token is
"$SEQUENCE_ID$", which will be replaced by the chosen
- sequence id when you click on it.
+ sequence id when you click on it.
</p>
<p>
eg.<br> UniRef100 =
Swissprot = http://www.expasy.org/uniprot/$SEQUENCE_ID$ <br> <br>
Links will also be made for any database cross references associated
with the sequence where the database name exactly matches a URL link
- name. In this case, the $SEQUENCE_ID$ string will be replaced with
+ name. In this case, the $DB_ACCESSION$ string will be replaced with
the accession string for the database cross-reference, rather than
- the sequence ID for the sequence (<em>since Jalview 2.4</em>).
+ the sequence ID for the sequence (<em>since Jalview 2.10.1</em>).
</p>
<p>
<strong>Regular Expression Substitution</strong><br> A url may
contain a string of the form $SEQUENCE_ID=/<em>regular
- expression</em>/=$. In this case, the regular expression will be
- applied to the full sequence ID string and the resulting match will
+ expression</em>/=$ or $DB_ACCESSION=/<em>regular expression</em>/=$.
+ In this case, the regular expression will be
+ applied to the full sequence ID or DB accession ID string and the resulting match will
be inserted into the URL. Groups of parentheses can be used to
specify which regions of the regular expression will be used to
generate the URL:
label.hide_columns_not_containing = Hide columns that do not contain
option.trim_retrieved_seqs = Trim retrieved sequences
label.trim_retrieved_sequences = When the reference sequence is longer than the sequence that you are working with, only keep the relevant subsequences.
-label.use_sequence_id_1 = Use $SEQUENCE_ID$ or $SEQUENCE_ID=/<regex>/=$
-label.use_sequence_id_2 = to embed sequence id in URL
-label.use_sequence_id_3 = Use $SEQUENCE_NAME$ similarly to embed sequence name
+label.use_sequence_id_1 = Use $DB_ACCESSION$ or $DB_ACCESSION=/<regex>/=$
+label.use_sequence_id_2 = to embed accession id in URL
+label.use_sequence_id_3 = Use $SEQUENCE_ID$ similarly to embed sequence id
label.use_sequence_id_4 =
label.ws_parameters_for = Parameters for {0}
label.switch_server = Switch server
label.column = Column
label.cant_map_cds = Unable to map CDS to protein\nCDS missing or incomplete
label.operation_failed = Operation failed
+label.SEQUENCE_ID_no_longer_used = $SEQUENCE_ID$ is no longer used for DB accessions
+label.SEQUENCE_ID_for_DB_ACCESSION1 = Please review your URL links in the 'Connections' tab of the Preferences window:
+label.SEQUENCE_ID_for_DB_ACCESSION2 = URL links using '$SEQUENCE_ID$' for DB accessions now use '$DB_ACCESSION$'.
+label.do_not_display_again = Do not display this message again
label.select_columns_not_containing = Seleccione las columnas que no contengan
option.trim_retrieved_seqs = Ajustar las secuencias recuperadas
label.trim_retrieved_sequences = Cuando la secuencia de referencia es más larga que la secuencia con la que está trabajando, sólo se mantienen las subsecuencias relevantes.
-label.use_sequence_id_1 = Utilice $SEQUENCE_ID$ o $SEQUENCE_ID=/<regex>/=$
-label.use_sequence_id_2 = para embeber el id de la secuencia en una URL
-label.use_sequence_id_3 = Utilice $SEQUENCE_NAME$ de manera similar para embeber
-label.use_sequence_id_4 = el nombre de la secuencia
+label.use_sequence_id_1 = Utilice $DB_ACCESSION$ o $DB_ACCESSION=/<regex>/=$
+label.use_sequence_id_2 = para embeber el ID de accesión en una URL
+label.use_sequence_id_3 = Utilice $SEQUENCE_ID$ de manera similar para embeber
+label.use_sequence_id_4 = el ID de la secuencia
label.ws_parameters_for = Parámetros para {0}
label.switch_server = Cambiar servidor
label.open_jabaws_web_page = Abra el página principal del servidor JABAWS en un navegador web
label.column = Columna
label.cant_map_cds = No se pudo mapear CDS a proteÃna\nDatos CDS faltantes o incompletos
label.operation_failed = Operación fallada
+label.SEQUENCE_ID_no_longer_used = $SEQUENCE_ID$ no se utiliza más para accesiones DB
+label.SEQUENCE_ID_for_DB_ACCESSION1 = Por favor, revise sus URLs en la pestaña 'Conexiones' de la ventana de Preferencias:
+label.SEQUENCE_ID_for_DB_ACCESSION2 = URL enlaza usando '$SEQUENCE_ID$' para accesiones DB ahora usar '$DB_ACCESSION$'.
+label.do_not_display_again = No mostrar este mensaje de nuevo
\ No newline at end of file
*/
package jalview.analysis;
-import jalview.analysis.ResidueCount.SymbolCounts;
import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.Annotation;
+import jalview.datamodel.Profile;
+import jalview.datamodel.ProfileI;
+import jalview.datamodel.ResidueCount;
import jalview.datamodel.SequenceI;
+import jalview.datamodel.ResidueCount.SymbolCounts;
import jalview.ext.android.SparseIntArray;
import jalview.util.Comparison;
import jalview.util.Format;
}
}
- public static final Profile[] calculate(List<SequenceI> list,
+ public static final ProfileI[] calculate(List<SequenceI> list,
int start, int end)
{
return calculate(list, start, end, false);
}
- public static final Profile[] calculate(List<SequenceI> sequences,
+ public static final ProfileI[] calculate(List<SequenceI> sequences,
int start, int end, boolean profile)
{
SequenceI[] seqs = new SequenceI[sequences.size()];
}
}
- Profile[] reply = new Profile[width];
+ ProfileI[] reply = new ProfileI[width];
if (end >= width)
{
* if true, store all symbol counts
*/
public static final void calculate(final SequenceI[] sequences,
- int start, int end, Profile[] result, boolean saveFullProfile)
+ int start, int end, ProfileI[] result, boolean saveFullProfile)
{
// long now = System.currentTimeMillis();
int seqCount = sequences.length;
int maxCount = residueCounts.getModalCount();
String maxResidue = residueCounts.getResiduesForCount(maxCount);
int gapCount = residueCounts.getGapCount();
- Profile profile = new Profile(seqCount, gapCount, maxCount,
+ ProfileI profile = new Profile(seqCount, gapCount, maxCount,
maxResidue);
if (saveFullProfile)
* number of sequences
*/
public static void completeConsensus(AlignmentAnnotation consensus,
- Profile[] profiles, int iStart, int width, boolean ignoreGaps,
+ ProfileI[] profiles, int iStart, int width, boolean ignoreGaps,
boolean showSequenceLogo, long nseq)
{
// long now = System.currentTimeMillis();
for (int i = iStart; i < width; i++)
{
- Profile profile;
+ ProfileI profile;
if (i >= profiles.length || ((profile = profiles[i]) == null))
{
/*
* the number of decimal places to format percentages to
* @return
*/
- static String getTooltip(Profile profile, float pid,
+ static String getTooltip(ProfileI profile, float pid,
boolean showSequenceLogo, boolean ignoreGaps, int dp)
{
ResidueCount counts = profile.getCounts();
* calculations
* @return
*/
- public static int[] extractProfile(Profile profile,
+ public static int[] extractProfile(ProfileI profile,
boolean ignoreGaps)
{
int[] rtnval = new int[64];
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.Annotation;
+import jalview.datamodel.ResidueCount;
+import jalview.datamodel.ResidueCount.SymbolCounts;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
-import jalview.ext.android.SparseIntArray;
import jalview.schemes.ResidueProperties;
+import jalview.util.Comparison;
import java.awt.Color;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.Vector;
/**
* Calculates conservation values for a given set of sequences
- *
- * @author $author$
- * @version $Revision$
*/
public class Conservation
{
+ /*
+ * need to have a minimum of 3% of sequences with a residue
+ * for it to be included in the conservation calculation
+ */
+ private static final int THRESHOLD_PERCENT = 3;
+
+ private static final int TOUPPERCASE = 'a' - 'A';
+
SequenceI[] sequences;
int start;
boolean seqNumsChanged = false; // updated after any change via calcSeqNum;
+ /*
+ * a map per column with {property, conservation} where conservation value is
+ * 1 (property is conserved), 0 (absence of property is conserved) or -1
+ * (property is not conserved i.e. column has residues with and without it)
+ */
Map<String, Integer>[] total;
boolean canonicaliseAa = true; // if true then conservation calculation will
private Sequence consSequence;
+ /*
+ * percentage of residues in a column to qualify for counting conservation
+ */
private int threshold;
private String name = "";
private String[] consSymbs;
/**
- * Creates a new Conservation object.
+ * Constructor using default threshold of 3%
*
* @param name
* Name of conservation
- * @param threshold
- * to count the residues in residueHash(). commonly used value is 3
* @param sequences
* sequences to be used in calculation
* @param start
* @param end
* end residue position
*/
+ public Conservation(String name, List<SequenceI> sequences, int start,
+ int end)
+ {
+ this(name, THRESHOLD_PERCENT, sequences, start, end);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param name
+ * Name of conservation
+ * @param threshold
+ * percentage of sequences at or below which property conservation is
+ * ignored
+ * @param sequences
+ * sequences to be used in calculation
+ * @param start
+ * start column position
+ * @param end
+ * end column position
+ */
public Conservation(String name, int threshold,
List<SequenceI> sequences, int start, int end)
{
*/
public void calculate()
{
- int jSize = sequences.length;
- // int[] values; // Replaces residueHash
- SparseIntArray values = new SparseIntArray();
+ int height = sequences.length;
total = new Map[maxLength];
- for (int i = start; i <= end; i++)
+ for (int column = start; column <= end; column++)
+ {
+ ResidueCount values = countResidues(column);
+
+ /*
+ * percentage count at or below which we ignore residues
+ */
+ int thresh = (threshold * height) / 100;
+
+ /*
+ * check observed residues in column and record whether each
+ * physico-chemical property is conserved (+1), absence conserved (0),
+ * or not conserved (-1)
+ * Using TreeMap means properties are displayed in alphabetical order
+ */
+ Map<String, Integer> resultHash = new TreeMap<String, Integer>();
+ SymbolCounts symbolCounts = values.getSymbolCounts();
+ char[] symbols = symbolCounts.symbols;
+ int[] counts = symbolCounts.values;
+ for (int j = 0; j < symbols.length; j++)
+ {
+ char c = symbols[j];
+ if (counts[j] > thresh)
+ {
+ recordConservation(resultHash, String.valueOf(c));
+ }
+ }
+ if (values.getGapCount() > thresh)
+ {
+ recordConservation(resultHash, "-");
+ }
+
+ if (total.length > 0)
+ {
+ total[column - start] = resultHash;
+ }
+ }
+ }
+
+ /**
+ * Updates the conservation results for an observed residue
+ *
+ * @param resultMap
+ * a map of {property, conservation} where conservation value is +1
+ * (all residues have the property), 0 (no residue has the property)
+ * or -1 (some do, some don't)
+ * @param res
+ */
+ protected static void recordConservation(Map<String, Integer> resultMap,
+ String res)
+ {
+ res = res.toUpperCase();
+ for (Entry<String, Map<String, Integer>> property : ResidueProperties.propHash
+ .entrySet())
{
- // values = new int[255];
- values.clear();
+ String propertyName = property.getKey();
+ Integer residuePropertyValue = property.getValue().get(res);
- for (int j = 0; j < jSize; j++)
+ if (!resultMap.containsKey(propertyName))
{
- if (sequences[j].getLength() > i)
+ /*
+ * first time we've seen this residue - note whether it has this property
+ */
+ if (residuePropertyValue != null)
{
- char c = sequences[j].getCharAt(i);
-
- if (canonicaliseAa)
- { // lookup the base aa code symbol
- c = (char) ResidueProperties.aaIndex[sequences[j].getCharAt(i)];
- if (c > 20)
- {
- c = '-';
- }
- else
- {
- // recover canonical aa symbol
- c = ResidueProperties.aa[c].charAt(0);
- }
- }
- else
- {
- // original behaviour - operate on ascii symbols directly
- // No need to check if its a '-'
- if (c == '.' || c == ' ')
- {
- c = '-';
- }
-
- c = toUpperCase(c);
- }
- // values[c]++;
- values.add(c, 1);
+ resultMap.put(propertyName, residuePropertyValue);
}
else
{
- // values['-']++;
- values.add('-', 1);
+ /*
+ * unrecognised residue - use default value for property
+ */
+ resultMap.put(propertyName, property.getValue().get("-"));
}
}
+ else
+ {
+ Integer currentResult = resultMap.get(propertyName);
+ if (currentResult.intValue() != -1
+ && !currentResult.equals(residuePropertyValue))
+ {
+ /*
+ * property is unconserved - residues seen both with and without it
+ */
+ resultMap.put(propertyName, Integer.valueOf(-1));
+ }
+ }
+ }
+ }
- // What is the count threshold to count the residues in residueHash()
- int thresh = (threshold * jSize) / 100;
+ /**
+ * Counts residues (upper-cased) and gaps in the given column
+ *
+ * @param column
+ * @return
+ */
+ protected ResidueCount countResidues(int column)
+ {
+ ResidueCount values = new ResidueCount(false);
- // loop over all the found residues
- // Hashtable<String, Integer> resultHash = new Hashtable<String,
- // Integer>();
- Map<String, Integer> resultHash = new TreeMap<String, Integer>();
- // for (char v = '-'; v < 'Z'; v++)
- for (int key = 0; key < values.size(); key++)
+ for (int row = 0; row < sequences.length; row++)
+ {
+ if (sequences[row].getLength() > column)
{
- char v = (char) values.keyAt(key);
- // if (values[v] > thresh)
- if (values.valueAt(key) > thresh)
+ char c = sequences[row].getCharAt(column);
+ if (canonicaliseAa)
{
- String res = String.valueOf(v);
-
- // Now loop over the properties
- for (String type : ResidueProperties.propHash.keySet())
- {
- Map<String, Integer> ht = ResidueProperties.propHash.get(type);
-
- // Have we ticked this before?
- if (!resultHash.containsKey(type))
- {
- if (ht.containsKey(res))
- {
- resultHash.put(type, ht.get(res));
- }
- else
- {
- resultHash.put(type, ht.get("-"));
- }
- }
- else if (!resultHash.get(type).equals(ht.get(res)))
- {
- resultHash.put(type, new Integer(-1));
- }
- }
+ int index = ResidueProperties.aaIndex[c];
+ c = index > 20 ? '-' : ResidueProperties.aa[index].charAt(0);
+ }
+ else
+ {
+ c = toUpperCase(c);
+ }
+ if (Comparison.isGap(c))
+ {
+ values.addGap();
+ }
+ else
+ {
+ values.add(c);
}
}
-
- if (total.length > 0)
+ else
{
- total[i - start] = resultHash;
+ values.addGap();
}
}
+ return values;
}
- /*****************************************************************************
- * count conservation for the j'th column of the alignment
+ /**
+ * Counts conservation and gaps for a column of the alignment
*
- * @return { gap count, conserved residue count}
+ * @return { 1 if fully conserved, else 0, gap count }
*/
- public int[] countConsNGaps(int j)
+ public int[] countConservationAndGaps(int column)
{
- int count = 0;
- int cons = 0;
- int nres = 0;
- int[] r = new int[2];
- char f = '$';
- int i, iSize = sequences.length;
- char c;
+ int gapCount = 0;
+ boolean fullyConserved = true;
+ int iSize = sequences.length;
- for (i = 0; i < iSize; i++)
+ if (iSize == 0)
+ {
+ return new int[] { 0, 0 };
+ }
+
+ char lastRes = '0';
+ for (int i = 0; i < iSize; i++)
{
- if (j >= sequences[i].getLength())
+ if (column >= sequences[i].getLength())
{
- count++;
+ gapCount++;
continue;
}
- c = sequences[i].getCharAt(j); // gaps do not have upper/lower case
+ char c = sequences[i].getCharAt(column); // gaps do not have upper/lower case
- if (jalview.util.Comparison.isGap((c)))
+ if (Comparison.isGap((c)))
{
- count++;
+ gapCount++;
}
else
{
c = toUpperCase(c);
- nres++;
-
- if (nres == 1)
+ if (lastRes == '0')
{
- f = c;
- cons++;
+ lastRes = c;
}
- else if (f == c)
+ if (c != lastRes)
{
- cons++;
+ fullyConserved = false;
}
}
}
- r[0] = (nres == cons) ? 1 : 0;
- r[1] = count;
-
+ int[] r = new int[] { fullyConserved ? 1 : 0, gapCount };
return r;
}
{
if ('a' <= c && c <= 'z')
{
- c -= (32); // 32 = 'a' - 'A'
+ c -= TOUPPERCASE;
}
return c;
}
/**
* Calculates the conservation sequence
*
- * @param consflag
- * if true, positive conservation; false calculates negative
- * conservation
- * @param percentageGaps
- * commonly used value is 25
+ * @param positiveOnly
+ * if true, calculate positive conservation; else calculate both
+ * positive and negative conservation
+ * @param maxPercentageGaps
+ * the percentage of gaps in a column, at or above which no
+ * conservation is asserted
*/
- public void verdict(boolean consflag, float percentageGaps)
+ public void verdict(boolean positiveOnly, float maxPercentageGaps)
{
+ // TODO call this at the end of calculate(), should not be a public method
+
StringBuilder consString = new StringBuilder(end);
// NOTE THIS SHOULD CHECK IF THE CONSEQUENCE ALREADY
consSymbs = new String[end - start + 1];
for (int i = start; i <= end; i++)
{
- int[] gapcons = countConsNGaps(i);
+ int[] gapcons = countConservationAndGaps(i);
+ boolean fullyConserved = gapcons[0] == 1;
int totGaps = gapcons[1];
- float pgaps = ((float) totGaps * 100) / sequences.length;
- StringBuilder positives = new StringBuilder(64);
- StringBuilder negatives = new StringBuilder(32);
- // consSymbs[i - start] = "";
+ float pgaps = (totGaps * 100f) / sequences.length;
- if (percentageGaps > pgaps)
+ if (maxPercentageGaps > pgaps)
{
Map<String, Integer> resultHash = total[i - start];
- // Now find the verdict
int count = 0;
+ StringBuilder positives = new StringBuilder(64);
+ StringBuilder negatives = new StringBuilder(32);
for (String type : resultHash.keySet())
{
int result = resultHash.get(type).intValue();
- // Do we want to count +ve conservation or +ve and -ve cons.?
- if (consflag)
+ if (result == -1)
{
- if (result == 1)
- {
- // consSymbs[i - start] = type + " " + consSymbs[i - start];
- positives.append(positives.length() == 0 ? "" : " ");
- positives.append(type);
- count++;
- }
+ /*
+ * not conserved (present or absent)
+ */
+ continue;
}
- else
+ count++;
+ if (result == 1)
{
- if (result != -1)
- {
- if (result == 0)
- {
- /*
- * add negatively conserved properties on the end
- */
- // consSymbs[i - start] = consSymbs[i - start] + " !" + type;
- negatives.append(negatives.length() == 0 ? "" : " ");
- negatives.append("!").append(type);
- }
- else
- {
- /*
- * put positively conserved properties on the front
- */
- // consSymbs[i - start] = type + " " + consSymbs[i - start];
- positives.append(positives.length() == 0 ? "" : " ");
- positives.append(type);
- }
- count++;
- }
+ /*
+ * positively conserved property (all residues have it)
+ */
+ positives.append(positives.length() == 0 ? "" : " ");
+ positives.append(type);
+ }
+ if (result == 0 && !positiveOnly)
+ {
+ /*
+ * absense of property is conserved (all residues lack it)
+ */
+ negatives.append(negatives.length() == 0 ? "" : " ");
+ negatives.append("!").append(type);
}
}
if (negatives.length() > 0)
}
else
{
- consString.append((gapcons[0] == 1) ? "*" : "+");
+ consString.append(fullyConserved ? "*" : "+");
}
}
else
*
* @param name
* - name of conservation
- * @param threshold
- * - minimum number of conserved residues needed to indicate
- * conservation (typically 3)
* @param seqs
* @param start
* first column in calculation window
* @param end
* last column in calculation window
- * @param posOrNeg
- * positive (true) or negative (false) conservation
- * @param consPercGaps
+ * @param positiveOnly
+ * calculate positive (true) or positive and negative (false)
+ * conservation
+ * @param maxPercentGaps
* percentage of gaps tolerated in column
* @param calcQuality
* flag indicating if alignment quality should be calculated
* @return Conservation object ready for use in visualization
*/
public static Conservation calculateConservation(String name,
- int threshold, List<SequenceI> seqs, int start, int end,
- boolean posOrNeg, int consPercGaps, boolean calcQuality)
+ List<SequenceI> seqs, int start, int end, boolean positiveOnly,
+ int maxPercentGaps, boolean calcQuality)
{
- Conservation cons = new Conservation(name, threshold, seqs, start, end);
+ Conservation cons = new Conservation(name, seqs, start, end);
cons.calculate();
- cons.verdict(posOrNeg, consPercGaps);
+ cons.verdict(positiveOnly, maxPercentGaps);
if (calcQuality)
{
return cons;
}
+
+ /**
+ * Returns the computed tooltip (annotation description) for a given column.
+ * The tip is empty if the conservation score is zero, otherwise holds the
+ * conserved properties (and, optionally, properties whose absence is
+ * conserved).
+ *
+ * @param column
+ * @return
+ */
+ String getTooltip(int column)
+ {
+ char[] sequence = getConsSequence().getSequence();
+ char val = column < sequence.length ? sequence[column] : '-';
+ boolean hasConservation = val != '-' && val != '0';
+ int consp = column - start;
+ String tip = (hasConservation && consp > -1 && consp < consSymbs.length) ? consSymbs[consp]
+ : "";
+ return tip;
+ }
}
package jalview.api;
import jalview.analysis.Conservation;
-import jalview.analysis.Profile;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentView;
import jalview.datamodel.CigarArray;
import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.ProfileI;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
ColumnSelection getColumnSelection();
- Profile[] getSequenceConsensusHash();
+ ProfileI[] getSequenceConsensusHash();
/**
* Get consensus data table for the cDNA complement of this alignment (if any)
*
* @param hconsensus
*/
- void setSequenceConsensusHash(Profile[] hconsensus);
+ void setSequenceConsensusHash(ProfileI[] hconsensus);
/**
* Set the cDNA complement consensus for the viewport
import jalview.analysis.AlignmentAnnotationUtils;
import jalview.analysis.AlignmentUtils;
import jalview.analysis.Conservation;
+import jalview.bin.Cache;
import jalview.commands.ChangeCaseCommand;
import jalview.commands.EditCommand;
import jalview.commands.EditCommand.Action;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
-import jalview.datamodel.DBRefEntry;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceGroup;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
if (links != null && links.size() > 0)
{
- Menu linkMenu = new Menu(MessageManager.getString("action.link"));
- for (int i = 0; i < links.size(); i++)
- {
- String link = links.elementAt(i);
- UrlLink urlLink = new UrlLink(link);
- if (!urlLink.isValid())
- {
- System.err.println(urlLink.getInvalidMessage());
- continue;
- }
- final String target = urlLink.getTarget(); // link.substring(0,
- // link.indexOf("|"));
- final String label = urlLink.getLabel();
- if (seq != null && urlLink.isDynamic())
- {
-
- // collect matching db-refs
- DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(
- seq.getDBRefs(), new String[] { target });
- // collect id string too
- String id = seq.getName();
- String descr = seq.getDescription();
- if (descr != null && descr.length() < 1)
- {
- descr = null;
- }
- if (dbr != null)
- {
- for (int r = 0; r < dbr.length; r++)
- {
- if (id != null && dbr[r].getAccessionId().equals(id))
- {
- // suppress duplicate link creation for the bare sequence ID
- // string with this link
- id = null;
- }
- // create Bare ID link for this RUL
- String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(),
- true);
- if (urls != null)
- {
- for (int u = 0; u < urls.length; u += 2)
- {
- addshowLink(linkMenu, label + "|" + urls[u], urls[u + 1]);
- }
- }
- }
- }
- if (id != null)
- {
- // create Bare ID link for this RUL
- String[] urls = urlLink.makeUrls(id, true);
- if (urls != null)
- {
- for (int u = 0; u < urls.length; u += 2)
- {
- addshowLink(linkMenu, label, urls[u + 1]);
- }
- }
- // addshowLink(linkMenu, target, url_pref + id + url_suff);
- }
- // Now construct URLs from description but only try to do it for regex
- // URL links
- if (descr != null && urlLink.getRegexReplace() != null)
- {
- // create link for this URL from description only if regex matches
- String[] urls = urlLink.makeUrls(descr, true);
- if (urls != null)
- {
- for (int u = 0; u < urls.length; u += 2)
- {
- addshowLink(linkMenu, label, urls[u + 1]);
- }
- }
- }
- }
- else
- {
- addshowLink(linkMenu, target, urlLink.getUrl_prefix()); // link.substring(link.lastIndexOf("|")+1));
- }
- /*
- * final String url;
- *
- * if (link.indexOf("$SEQUENCE_ID$") > -1) { // Substitute SEQUENCE_ID
- * string and any matching database reference accessions String url_pref
- * = link.substring(link.indexOf("|") + 1,
- * link.indexOf("$SEQUENCE_ID$"));
- *
- * String url_suff = link.substring(link.indexOf("$SEQUENCE_ID$") + 13);
- * // collect matching db-refs DBRefEntry[] dbr =
- * jalview.util.DBRefUtils.selectRefs(seq.getDBRef(), new
- * String[]{target}); // collect id string too String id =
- * seq.getName(); if (id.indexOf("|") > -1) { id =
- * id.substring(id.lastIndexOf("|") + 1); } if (dbr!=null) { for (int
- * r=0;r<dbr.length; r++) { if (dbr[r].getAccessionId().equals(id)) { //
- * suppress duplicate link creation for the bare sequence ID string with
- * this link id = null; } addshowLink(linkMenu,
- * dbr[r].getSource()+"|"+dbr[r].getAccessionId(), target,
- * url_pref+dbr[r].getAccessionId()+url_suff); } } if (id!=null) { //
- * create Bare ID link for this RUL addshowLink(linkMenu, target,
- * url_pref + id + url_suff); } } else { addshowLink(linkMenu, target,
- * link.substring(link.lastIndexOf("|")+1)); }
- */
- }
- if (linkMenu.getItemCount() > 0)
- {
- if (seq != null)
- {
- seqMenu.add(linkMenu);
- }
- else
- {
- add(linkMenu);
- }
- }
+ addFeatureLinks(seq, links);
}
+
// TODO: add group link menu entry here
if (seq != null)
{
}
/**
+ * Adds a 'Link' menu item with a sub-menu item for each hyperlink provided.
+ *
+ * @param seq
+ * @param links
+ */
+ void addFeatureLinks(final SequenceI seq, List<String> links)
+ {
+ Menu linkMenu = new Menu(MessageManager.getString("action.link"));
+ Map<String, List<String>> linkset = new LinkedHashMap<String, List<String>>();
+
+ for (String link : links)
+ {
+ UrlLink urlLink = null;
+ try
+ {
+ urlLink = new UrlLink(link);
+ } catch (Exception foo)
+ {
+ Cache.log.error("Exception for URLLink '" + link + "'", foo);
+ continue;
+ }
+
+ if (!urlLink.isValid())
+ {
+ Cache.log.error(urlLink.getInvalidMessage());
+ continue;
+ }
+
+ urlLink.createLinksFromSeq(seq, linkset);
+ }
+
+ addshowLinks(linkMenu, linkset.values());
+
+ if (linkMenu.getItemCount() > 0)
+ {
+ if (seq != null)
+ {
+ seqMenu.add(linkMenu);
+ }
+ else
+ {
+ add(linkMenu);
+ }
+ }
+ }
+
+ private void addshowLinks(Menu linkMenu, Collection<List<String>> linkset)
+ {
+ for (List<String> linkstrset : linkset)
+ {
+ // split linkstr into label and url
+ addshowLink(linkMenu, linkstrset.get(1), linkstrset.get(3));
+ }
+ }
+
+ /**
* Build menus for annotation types that may be shown or hidden, and for
* 'reference annotations' that may be added to the alignment.
*/
if (conservationMenuItem.getState())
{
-
- sg.cs.setConservation(Conservation.calculateConservation("Group", 3,
- sg.getSequences(ap.av.getHiddenRepSequences()), 0, ap.av
- .getAlignment().getWidth(), false, ap.av
- .getConsPercGaps(), false));
+ sg.cs.setConservation(Conservation.calculateConservation("Group", sg
+ .getSequences(ap.av.getHiddenRepSequences()), 0, ap.av
+ .getAlignment().getWidth(), false, ap.av.getConsPercGaps(),
+ false));
SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());
SliderPanel.showConservationSlider();
}
url = null;
continue;
}
- ;
+
+ if (urlLink.usesDBAccession())
+ {
+ // this URL requires an accession id, not the name of a sequence
+ url = null;
+ continue;
+ }
+
if (!urlLink.isValid())
{
System.err.println(urlLink.getInvalidMessage());
if (av.getGlobalColourScheme() != null
&& av.getGlobalColourScheme().conservationApplied())
{
- Conservation c = new Conservation("Group", 3,
- sg.getSequences(null), sg.getStartRes(), sg.getEndRes());
+ Conservation c = new Conservation("Group", sg.getSequences(null),
+ sg.getStartRes(), sg.getEndRes());
c.calculate();
c.verdict(false, av.getConsPercGaps());
-package jalview.analysis;
+package jalview.datamodel;
/**
- * A data bean to hold the result of computing a profile for a column of an
- * alignment
+ * A profile for one column of an alignment
*
* @author gmcarstairs
*
*/
-public class Profile
+public class Profile implements ProfileI
{
/*
- * counts of keys (chars)
+ * an object holding counts of symbols in the profile
*/
private ResidueCount counts;
/*
- * the number of sequences in the profile
+ * the number of sequences (gapped or not) in the profile
*/
private int height;
this.modalResidue = modalRes;
}
- /**
- * Set the full profile of counts
- *
- * @param residueCounts
+ /* (non-Javadoc)
+ * @see jalview.datamodel.ProfileI#setCounts(jalview.datamodel.ResidueCount)
*/
+ @Override
public void setCounts(ResidueCount residueCounts)
{
this.counts = residueCounts;
}
- /**
- * Returns the percentage identity of the profile, i.e. the highest proportion
- * of conserved (equal) symbols. The percentage is as a fraction of all
- * sequences, or only ungapped sequences if flag ignoreGaps is set true.
- *
- * @param ignoreGaps
- * @return
+ /* (non-Javadoc)
+ * @see jalview.datamodel.ProfileI#getPercentageIdentity(boolean)
*/
+ @Override
public float getPercentageIdentity(boolean ignoreGaps)
{
if (height == 0)
return pid;
}
- /**
- * Returns the full symbol counts for this profile
- *
- * @return
+ /* (non-Javadoc)
+ * @see jalview.datamodel.ProfileI#getCounts()
*/
+ @Override
public ResidueCount getCounts()
{
return counts;
}
- /**
- * Returns the number of sequences in the profile
- *
- * @return
+ /* (non-Javadoc)
+ * @see jalview.datamodel.ProfileI#getHeight()
*/
+ @Override
public int getHeight()
{
return height;
}
- /**
- * Returns the number of sequences in the profile which had a gap character
- * (or were too short to be included in this column's profile)
- *
- * @return
+ /* (non-Javadoc)
+ * @see jalview.datamodel.ProfileI#getGapped()
*/
+ @Override
public int getGapped()
{
return gapped;
}
- /**
- * Returns the highest count for any symbol(s) in the profile
- *
- * @return
+ /* (non-Javadoc)
+ * @see jalview.datamodel.ProfileI#getMaxCount()
*/
+ @Override
public int getMaxCount()
{
return maxCount;
}
- /**
- * Returns the symbol (or concatenated symbols) which have the highest count
- * in the profile, or an empty string if there were no symbols counted
- *
- * @return
+ /* (non-Javadoc)
+ * @see jalview.datamodel.ProfileI#getModalResidue()
*/
+ @Override
public String getModalResidue()
{
return modalResidue;
}
- /**
- * Answers the number of non-gapped sequences in the profile
- *
- * @return
+ /* (non-Javadoc)
+ * @see jalview.datamodel.ProfileI#getNonGapped()
*/
+ @Override
public int getNonGapped()
{
return height - gapped;
--- /dev/null
+package jalview.datamodel;
+
+public interface ProfileI
+{
+
+ /**
+ * Set the full profile of counts
+ *
+ * @param residueCounts
+ */
+ public abstract void setCounts(ResidueCount residueCounts);
+
+ /**
+ * Returns the percentage identity of the profile, i.e. the highest proportion
+ * of conserved (equal) symbols. The percentage is as a fraction of all
+ * sequences, or only ungapped sequences if flag ignoreGaps is set true.
+ *
+ * @param ignoreGaps
+ * @return
+ */
+ public abstract float getPercentageIdentity(boolean ignoreGaps);
+
+ /**
+ * Returns the full symbol counts for this profile
+ *
+ * @return
+ */
+ public abstract ResidueCount getCounts();
+
+ /**
+ * Returns the number of sequences in the profile
+ *
+ * @return
+ */
+ public abstract int getHeight();
+
+ /**
+ * Returns the number of sequences in the profile which had a gap character
+ * (or were too short to be included in this column's profile)
+ *
+ * @return
+ */
+ public abstract int getGapped();
+
+ /**
+ * Returns the highest count for any symbol(s) in the profile
+ *
+ * @return
+ */
+ public abstract int getMaxCount();
+
+ /**
+ * Returns the symbol (or concatenated symbols) which have the highest count
+ * in the profile, or an empty string if there were no symbols counted
+ *
+ * @return
+ */
+ public abstract String getModalResidue();
+
+ /**
+ * Answers the number of non-gapped sequences in the profile
+ *
+ * @return
+ */
+ public abstract int getNonGapped();
+
+}
\ No newline at end of file
-package jalview.analysis;
+package jalview.datamodel;
import jalview.util.Comparison;
import jalview.util.Format;
/*
* keeps track of the maximum count value recorded
- * (if this class every allows decrements, would need to
+ * (if this class ever allows decrements, would need to
* calculate this on request instead)
*/
int maxCount;
import jalview.analysis.AAFrequency;
import jalview.analysis.Conservation;
-import jalview.analysis.Profile;
import jalview.schemes.ColourSchemeI;
import java.awt.Color;
boolean upd = false;
try
{
- Profile[] cnsns = AAFrequency.calculate(sequences, startRes,
+ ProfileI[] cnsns = AAFrequency.calculate(sequences, startRes,
endRes + 1, showSequenceLogo);
if (consensus != null)
{
if ((conservation != null)
|| (cs != null && cs.conservationApplied()))
{
- Conservation c = new Conservation(groupName, 3, sequences,
- startRes, endRes + 1);
+ Conservation c = new Conservation(groupName, sequences, startRes,
+ endRes + 1);
c.calculate();
c.verdict(false, consPercGaps);
if (conservation != null)
c.completeAnnotations(conservation, null, startRes, endRes + 1);
}
- public Profile[] consensusData = null;
+ public ProfileI[] consensusData = null;
- private void _updateConsensusRow(Profile[] cnsns, long nseq)
+ private void _updateConsensusRow(ProfileI[] cnsns, long nseq)
{
if (consensus == null)
{
import java.util.concurrent.Semaphore;
import javax.swing.AbstractAction;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
import javax.swing.DefaultDesktopManager;
import javax.swing.DesktopManager;
import javax.swing.JButton;
+import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
showNews.setVisible(false);
+ checkURLLinks();
+
this.addWindowListener(new WindowAdapter()
{
@Override
new Thread(jvq).start();
}
+ public void checkURLLinks()
+ {
+ // Thread off the URL link checker
+ addDialogThread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ if (Cache.getDefault("CHECKURLLINKS", true))
+ {
+ // check in case URL links use old style tokens ($SEQUENCE_ID$ for
+ // sequence id _or_ accession id)
+ JPanel msgPanel = new JPanel();
+ msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.PAGE_AXIS));
+ msgPanel.add(Box.createVerticalGlue());
+ JLabel msg = new JLabel(
+ MessageManager
+ .getString("label.SEQUENCE_ID_for_DB_ACCESSION1"));
+ JLabel msg2 = new JLabel(
+ MessageManager
+ .getString("label.SEQUENCE_ID_for_DB_ACCESSION2"));
+ msgPanel.add(msg);
+ msgPanel.add(msg2);
+
+ final JCheckBox jcb = new JCheckBox(
+ MessageManager.getString("label.do_not_display_again"));
+ jcb.addActionListener(new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ // update Cache settings if checkbox is selected
+ if (jcb.isSelected())
+ {
+ Cache.setProperty("CHECKURLLINKS", "false");
+ }
+ }
+ });
+ msgPanel.add(jcb);
+
+ JOptionPane.showMessageDialog(null, msgPanel, MessageManager
+ .getString("label.SEQUENCE_ID_no_longer_used"),
+ JOptionPane.WARNING_MESSAGE);
+ }
+ }
+ });
+ }
+
/**
* Proxy class for JDesktopPane which optionally displays the current memory
* usage and highlights the desktop area with a red bar if free memory runs
url = null;
continue;
}
- ;
+
+ if (urlLink.usesDBAccession())
+ {
+ // this URL requires an accession id, not the name of a sequence
+ url = null;
+ continue;
+ }
+
if (!urlLink.isValid())
{
jalview.bin.Cache.log.error(urlLink.getInvalidMessage());
}
if (jGroup.getConsThreshold() != 0)
{
- Conservation c = new Conservation("All", 3,
- sg.getSequences(null), 0, sg.getWidth() - 1);
+ Conservation c = new Conservation("All", sg.getSequences(null),
+ 0, sg.getWidth() - 1);
c.calculate();
c.verdict(false, 25);
sg.cs.setConservation(c);
if (groups[i].getConsThreshold() != 0)
{
- Conservation c = new Conservation("All", 3,
- sg.getSequences(null), 0, sg.getWidth() - 1);
+ Conservation c = new Conservation("All", sg.getSequences(null),
+ 0, sg.getWidth() - 1);
c.calculate();
c.verdict(false, 25);
sg.cs.setConservation(c);
import jalview.schemes.TurnColourScheme;
import jalview.schemes.UserColourScheme;
import jalview.schemes.ZappoColourScheme;
-import jalview.util.DBRefUtils;
import jalview.util.GroupUrlLink;
import jalview.util.GroupUrlLink.UrlStringTooLongException;
import jalview.util.MessageManager;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Hashtable;
import java.util.LinkedHashMap;
void addFeatureLinks(final SequenceI seq, List<String> links)
{
JMenu linkMenu = new JMenu(MessageManager.getString("action.link"));
- List<String> linkset = new ArrayList<String>();
+ Map<String, List<String>> linkset = new LinkedHashMap<String, List<String>>();
+
for (String link : links)
{
UrlLink urlLink = null;
Cache.log.error("Exception for URLLink '" + link + "'", foo);
continue;
}
- ;
+
if (!urlLink.isValid())
{
Cache.log.error(urlLink.getInvalidMessage());
continue;
}
- final String label = urlLink.getLabel();
-
- // collect id string too
- String id = seq.getName();
- String descr = seq.getDescription();
- if (descr != null && descr.length() < 1)
- {
- descr = null;
- }
-
- if (seq != null && urlLink.usesSeqId()) // link is ID
- {
- // collect matching db-refs
- DBRefEntry[] dbr = DBRefUtils.selectRefs(seq.getDBRefs(),
- new String[] { urlLink.getTarget() });
-
- // if there are any dbrefs which match up with the link
- if (dbr != null)
- {
- for (int r = 0; r < dbr.length; r++)
- {
- if (id != null && dbr[r].getAccessionId().equals(id))
- {
- // suppress duplicate link creation for the bare sequence ID
- // string with this link
- id = null;
- }
- // create Bare ID link for this URL
- createBareURLLink(urlLink, dbr[r].getAccessionId(), linkset,
- linkMenu, label, true);
- }
- }
- // Create urls from description but only for URL links which are regex
- // links
- if (descr != null && urlLink.getRegexReplace() != null)
- {
- // create link for this URL from description where regex matches
- createBareURLLink(urlLink, descr, linkset, linkMenu, label, false);
- }
+ urlLink.createLinksFromSeq(seq, linkset);
+ }
- }
- else if (seq != null && !urlLink.usesSeqId()) // link is name
- {
- if (id != null)
- {
- // create Bare ID link for this URL
- createBareURLLink(urlLink, id, linkset, linkMenu, label, false);
- }
- // Create urls from description but only for URL links which are regex
- // links
- if (descr != null && urlLink.getRegexReplace() != null)
- {
- // create link for this URL from description where regex matches
- createBareURLLink(urlLink, descr, linkset, linkMenu, label, false);
- }
- }
- else
- {
- if (!linkset.contains(label + "|" + urlLink.getUrl_prefix()))
- {
- linkset.add(label + "|" + urlLink.getUrl_prefix());
- // Add a non-dynamic link
- addshowLink(linkMenu, label, urlLink.getUrl_prefix());
- }
- }
+ addshowLinks(linkMenu, linkset.values());
- }
if (sequence != null)
{
sequenceMenu.add(linkMenu);
}
}
- /*
- * Create a bare URL Link
- */
- private void createBareURLLink(UrlLink urlLink, String id,
- List<String> linkset, JMenu linkMenu, String label,
- Boolean addSepToLabel)
- {
- String[] urls = urlLink.makeUrls(id, true);
- if (urls != null)
- {
- for (int u = 0; u < urls.length; u += 2)
- {
- if (!linkset.contains(urls[u] + "|" + urls[u + 1]))
- {
- linkset.add(urls[u] + "|" + urls[u + 1]);
- if (addSepToLabel)
- {
- addshowLink(linkMenu, label + "|" + urls[u], urls[u + 1]);
- }
- else
- {
- addshowLink(linkMenu, label, urls[u + 1]);
- }
- }
- }
- }
- }
+
/**
* Add annotation types to 'Show annotations' and/or 'Hide annotations' menus.
}
}
+ private void addshowLinks(JMenu linkMenu, Collection<List<String>> linkset)
+ {
+ for (List<String> linkstrset : linkset)
+ {
+ // split linkstr into label and url
+ addshowLink(linkMenu, linkstrset.get(1), linkstrset.get(3));
+ }
+ }
+
/**
* add a show URL menu item to the given linkMenu
*
if (conservationMenuItem.isSelected())
{
// JBPNote: Conservation name shouldn't be i18n translated
- Conservation c = new Conservation("Group", 3, sg.getSequences(ap.av
+ Conservation c = new Conservation("Group", sg.getSequences(ap.av
.getHiddenRepSequences()), sg.getStartRes(),
sg.getEndRes() + 1);
package jalview.gui;
import static jalview.util.UrlConstants.EMBLEBI_STRING;
-import static jalview.util.UrlConstants.OLD_EMBLEBI_STRING;
+import static jalview.util.UrlConstants.DB_ACCESSION;
import static jalview.util.UrlConstants.SEQUENCE_ID;
-import static jalview.util.UrlConstants.SEQUENCE_NAME;
import static jalview.util.UrlConstants.SRS_STRING;
import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
String name = st.nextToken();
String url = st.nextToken();
// check for '|' within a regex
- int rxstart = url.indexOf("$" + SEQUENCE_ID + "$");
+ int rxstart = url.indexOf("$" + DB_ACCESSION + "$");
if (rxstart == -1)
{
- rxstart = url.indexOf("$" + SEQUENCE_NAME + "$");
+ rxstart = url.indexOf("$" + SEQUENCE_ID + "$");
}
while (rxstart == -1 && url.indexOf("/=$") == -1)
{
{
sequenceURLLinks.setElementAt(EMBLEBI_STRING, srsPos);
}
- // upgrade old EMBL-EBI link
- int emblPos = sequenceURLLinks.indexOf(OLD_EMBLEBI_STRING);
- if (emblPos > -1)
- {
- sequenceURLLinks.setElementAt(EMBLEBI_STRING, emblPos);
- }
}
/**
if (aps[a].av.getGlobalColourScheme() != null
&& aps[a].av.getGlobalColourScheme().conservationApplied())
{
- Conservation c = new Conservation("Group", 3,
- sg.getSequences(null), sg.getStartRes(), sg.getEndRes());
+ Conservation c = new Conservation("Group", sg.getSequences(null),
+ sg.getStartRes(), sg.getEndRes());
c.calculate();
c.verdict(false, aps[a].av.getConsPercGaps());
sg.cs.setConservation(c);
else if (key.equalsIgnoreCase("consThreshold"))
{
sg.cs.setConservationInc(Integer.parseInt(value));
- Conservation c = new Conservation("Group", 3,
- sg.getSequences(null), sg.getStartRes(),
- sg.getEndRes() + 1);
+ Conservation c = new Conservation("Group", sg.getSequences(null),
+ sg.getStartRes(), sg.getEndRes() + 1);
c.calculate();
c.verdict(false, 25); // TODO: refer to conservation percent threshold
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.io.gff.GffConstants;
-import jalview.util.DBRefUtils;
import jalview.util.UrlLink;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
{
try
{
- for (String[] urllink : createLinksFrom(null, urlstring))
+ for (List<String> urllink : createLinksFrom(null, urlstring))
{
sb.append("<br/> <a href=\""
- + urllink[3]
+ + urllink.get(3)
+ "\" target=\""
- + urllink[0]
+ + urllink.get(0)
+ "\">"
- + (urllink[0].toLowerCase().equals(
- urllink[1].toLowerCase()) ? urllink[0]
- : (urllink[0] + ":" + urllink[1]))
+ + (urllink.get(0).toLowerCase()
+ .equals(urllink.get(1).toLowerCase()) ? urllink
+ .get(0) : (urllink.get(0) + ":" + urllink
+ .get(1)))
+ "</a></br>");
}
} catch (Exception x)
*
* @param seq
* @param link
- * @return String[][] { String[] { link target, link label, dynamic component
- * inserted (if any), url }}
+ * @return Collection< List<String> > { List<String> { link target, link
+ * label, dynamic component inserted (if any), url }}
*/
- String[][] createLinksFrom(SequenceI seq, String link)
+ Collection<List<String>> createLinksFrom(SequenceI seq, String link)
{
- List<String[]> urlSets = new ArrayList<String[]>();
- List<String> uniques = new ArrayList<String>();
+ Map<String, List<String>> urlSets = new LinkedHashMap<String, List<String>>();
UrlLink urlLink = new UrlLink(link);
if (!urlLink.isValid())
{
System.err.println(urlLink.getInvalidMessage());
return null;
}
- if (seq != null && urlLink.isDynamic())
- {
- urlSets.addAll(createDynamicLinks(seq, urlLink, uniques));
- }
- else
- {
- String target = urlLink.getTarget();
- String label = urlLink.getLabel();
- String unq = label + "|" + urlLink.getUrl_prefix();
- if (!uniques.contains(unq))
- {
- uniques.add(unq);
- urlSets.add(new String[] { target, label, null,
- urlLink.getUrl_prefix() });
- }
- }
-
- return urlSets.toArray(new String[][] {});
- }
- /**
- * Formats and returns a list of dynamic href links
- *
- * @param seq
- * @param urlLink
- * @param uniques
- */
- List<String[]> createDynamicLinks(SequenceI seq, UrlLink urlLink,
- List<String> uniques)
- {
- List<String[]> result = new ArrayList<String[]>();
- final String target = urlLink.getTarget();
- final String label = urlLink.getLabel();
+ urlLink.createLinksFromSeq(seq, urlSets);
- // collect matching db-refs
- DBRefEntry[] dbr = DBRefUtils.selectRefs(seq.getDBRefs(),
- new String[] { target });
- // collect id string too
- String id = seq.getName();
- String descr = seq.getDescription();
- if (descr != null && descr.length() < 1)
- {
- descr = null;
- }
- if (dbr != null)
- {
- for (int r = 0; r < dbr.length; r++)
- {
- if (id != null && dbr[r].getAccessionId().equals(id))
- {
- // suppress duplicate link creation for the bare sequence ID
- // string with this link
- id = null;
- }
- // create Bare ID link for this URL
- String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(), true);
- if (urls != null)
- {
- for (int u = 0; u < urls.length; u += 2)
- {
- String unq = urls[u] + "|" + urls[u + 1];
- if (!uniques.contains(unq))
- {
- result.add(new String[] { target, label, urls[u], urls[u + 1] });
- uniques.add(unq);
- }
- }
- }
- }
- }
- if (id != null)
- {
- // create Bare ID link for this URL
- String[] urls = urlLink.makeUrls(id, true);
- if (urls != null)
- {
- for (int u = 0; u < urls.length; u += 2)
- {
- String unq = urls[u] + "|" + urls[u + 1];
- if (!uniques.contains(unq))
- {
- result.add(new String[] { target, label, urls[u], urls[u + 1] });
- uniques.add(unq);
- }
- }
- }
- }
- if (descr != null && urlLink.getRegexReplace() != null)
- {
- // create link for this URL from description only if regex matches
- String[] urls = urlLink.makeUrls(descr, true);
- if (urls != null)
- {
- for (int u = 0; u < urls.length; u += 2)
- {
- String unq = urls[u] + "|" + urls[u + 1];
- if (!uniques.contains(unq))
- {
- result.add(new String[] { target, label, urls[u], urls[u + 1] });
- uniques.add(unq);
- }
- }
- }
- }
- return result;
+ return urlSets.values();
}
public void createSequenceAnnotationReport(final StringBuffer tip,
import jalview.analysis.AAFrequency;
import jalview.analysis.CodingUtils;
-import jalview.analysis.Profile;
import jalview.analysis.Rna;
import jalview.analysis.StructureFrequency;
import jalview.api.AlignViewportI;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.Annotation;
import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.ProfileI;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ResidueProperties;
import jalview.util.Platform;
private ColumnSelection columnSelection;
- private Profile[] hconsensus;
+ private ProfileI[] hconsensus;
private Hashtable[] complementConsensus;
*/
package jalview.schemes;
-import jalview.analysis.Profile;
import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.ProfileI;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
/**
* assign the given consensus profile for the colourscheme
*/
- public void setConsensus(Profile[] hconsensus);
+ public void setConsensus(ProfileI[] hconsensus);
/**
* assign the given conservation to the colourscheme
package jalview.schemes;
import jalview.analysis.Conservation;
-import jalview.analysis.Profile;
+import jalview.datamodel.ProfileI;
/**
* Colourscheme that takes its colours from some other colourscheme
}
@Override
- public void setConsensus(Profile[] consensus)
+ public void setConsensus(ProfileI[] consensus)
{
if (colourScheme != null)
{
package jalview.schemes;
import jalview.analysis.Conservation;
-import jalview.analysis.Profile;
import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.ProfileI;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
import jalview.util.ColorUtils;
/*
* Consensus data indexed by column
*/
- Profile[] consensus;
+ ProfileI[] consensus;
/*
* Conservation string as a char array
* DOCUMENT ME!
*/
@Override
- public void setConsensus(Profile[] consensus)
+ public void setConsensus(ProfileI[] consensus)
{
if (consensus == null)
{
purinepyrimidineIndex['n'] = 2;
}
+ private static final Integer ONE = Integer.valueOf(1);
+
+ private static final Integer ZERO = Integer.valueOf(0);
+
static
{
- aa3Hash.put("ALA", Integer.valueOf(0));
- aa3Hash.put("ARG", Integer.valueOf(1));
+ aa3Hash.put("ALA", ZERO);
+ aa3Hash.put("ARG", ONE);
aa3Hash.put("ASN", Integer.valueOf(2));
aa3Hash.put("ASP", Integer.valueOf(3)); // D
aa3Hash.put("CYS", Integer.valueOf(4));
static
{
- hydrophobic.put("I", Integer.valueOf(1));
- hydrophobic.put("L", Integer.valueOf(1));
- hydrophobic.put("V", Integer.valueOf(1));
- hydrophobic.put("C", Integer.valueOf(1));
- hydrophobic.put("A", Integer.valueOf(1));
- hydrophobic.put("G", Integer.valueOf(1));
- hydrophobic.put("M", Integer.valueOf(1));
- hydrophobic.put("F", Integer.valueOf(1));
- hydrophobic.put("Y", Integer.valueOf(1));
- hydrophobic.put("W", Integer.valueOf(1));
- hydrophobic.put("H", Integer.valueOf(1));
- hydrophobic.put("K", Integer.valueOf(1));
- hydrophobic.put("X", Integer.valueOf(1));
- hydrophobic.put("-", Integer.valueOf(1));
- hydrophobic.put("*", Integer.valueOf(1));
- hydrophobic.put("R", Integer.valueOf(0));
- hydrophobic.put("E", Integer.valueOf(0));
- hydrophobic.put("Q", Integer.valueOf(0));
- hydrophobic.put("D", Integer.valueOf(0));
- hydrophobic.put("N", Integer.valueOf(0));
- hydrophobic.put("S", Integer.valueOf(0));
- hydrophobic.put("T", Integer.valueOf(0));
- hydrophobic.put("P", Integer.valueOf(0));
+ hydrophobic.put("I", ONE);
+ hydrophobic.put("L", ONE);
+ hydrophobic.put("V", ONE);
+ hydrophobic.put("C", ONE);
+ hydrophobic.put("A", ONE);
+ hydrophobic.put("G", ONE);
+ hydrophobic.put("M", ONE);
+ hydrophobic.put("F", ONE);
+ hydrophobic.put("Y", ONE);
+ hydrophobic.put("W", ONE);
+ hydrophobic.put("H", ONE);
+ hydrophobic.put("K", ONE);
+ hydrophobic.put("X", ONE);
+ hydrophobic.put("-", ONE);
+ hydrophobic.put("*", ONE);
+ hydrophobic.put("R", ZERO);
+ hydrophobic.put("E", ZERO);
+ hydrophobic.put("Q", ZERO);
+ hydrophobic.put("D", ZERO);
+ hydrophobic.put("N", ZERO);
+ hydrophobic.put("S", ZERO);
+ hydrophobic.put("T", ZERO);
+ hydrophobic.put("P", ZERO);
}
static
{
- polar.put("Y", Integer.valueOf(1));
- polar.put("W", Integer.valueOf(1));
- polar.put("H", Integer.valueOf(1));
- polar.put("K", Integer.valueOf(1));
- polar.put("R", Integer.valueOf(1));
- polar.put("E", Integer.valueOf(1));
- polar.put("Q", Integer.valueOf(1));
- polar.put("D", Integer.valueOf(1));
- polar.put("N", Integer.valueOf(1));
- polar.put("S", Integer.valueOf(1));
- polar.put("T", Integer.valueOf(1));
- polar.put("X", Integer.valueOf(1));
- polar.put("-", Integer.valueOf(1));
- polar.put("*", Integer.valueOf(1));
- polar.put("I", Integer.valueOf(0));
- polar.put("L", Integer.valueOf(0));
- polar.put("V", Integer.valueOf(0));
- polar.put("C", Integer.valueOf(0));
- polar.put("A", Integer.valueOf(0));
- polar.put("G", Integer.valueOf(0));
- polar.put("M", Integer.valueOf(0));
- polar.put("F", Integer.valueOf(0));
- polar.put("P", Integer.valueOf(0));
+ polar.put("Y", ONE);
+ polar.put("W", ONE);
+ polar.put("H", ONE);
+ polar.put("K", ONE);
+ polar.put("R", ONE);
+ polar.put("E", ONE);
+ polar.put("Q", ONE);
+ polar.put("D", ONE);
+ polar.put("N", ONE);
+ polar.put("S", ONE);
+ polar.put("T", ONE);
+ polar.put("X", ONE);
+ polar.put("-", ONE);
+ polar.put("*", ONE);
+ polar.put("I", ZERO);
+ polar.put("L", ZERO);
+ polar.put("V", ZERO);
+ polar.put("C", ZERO);
+ polar.put("A", ZERO);
+ polar.put("G", ZERO);
+ polar.put("M", ZERO);
+ polar.put("F", ZERO);
+ polar.put("P", ZERO);
}
static
{
- small.put("I", Integer.valueOf(0));
- small.put("L", Integer.valueOf(0));
- small.put("V", Integer.valueOf(1));
- small.put("C", Integer.valueOf(1));
- small.put("A", Integer.valueOf(1));
- small.put("G", Integer.valueOf(1));
- small.put("M", Integer.valueOf(0));
- small.put("F", Integer.valueOf(0));
- small.put("Y", Integer.valueOf(0));
- small.put("W", Integer.valueOf(0));
- small.put("H", Integer.valueOf(0));
- small.put("K", Integer.valueOf(0));
- small.put("R", Integer.valueOf(0));
- small.put("E", Integer.valueOf(0));
- small.put("Q", Integer.valueOf(0));
- small.put("D", Integer.valueOf(1));
- small.put("N", Integer.valueOf(1));
- small.put("S", Integer.valueOf(1));
- small.put("T", Integer.valueOf(1));
- small.put("P", Integer.valueOf(1));
- small.put("-", Integer.valueOf(1));
- small.put("*", Integer.valueOf(1));
+ small.put("I", ZERO);
+ small.put("L", ZERO);
+ small.put("V", ONE);
+ small.put("C", ONE);
+ small.put("A", ONE);
+ small.put("G", ONE);
+ small.put("M", ZERO);
+ small.put("F", ZERO);
+ small.put("Y", ZERO);
+ small.put("W", ZERO);
+ small.put("H", ZERO);
+ small.put("K", ZERO);
+ small.put("R", ZERO);
+ small.put("E", ZERO);
+ small.put("Q", ZERO);
+ small.put("D", ONE);
+ small.put("N", ONE);
+ small.put("S", ONE);
+ small.put("T", ONE);
+ small.put("P", ONE);
+ small.put("-", ONE);
+ small.put("*", ONE);
}
static
{
- positive.put("I", Integer.valueOf(0));
- positive.put("L", Integer.valueOf(0));
- positive.put("V", Integer.valueOf(0));
- positive.put("C", Integer.valueOf(0));
- positive.put("A", Integer.valueOf(0));
- positive.put("G", Integer.valueOf(0));
- positive.put("M", Integer.valueOf(0));
- positive.put("F", Integer.valueOf(0));
- positive.put("Y", Integer.valueOf(0));
- positive.put("W", Integer.valueOf(0));
- positive.put("H", Integer.valueOf(1));
- positive.put("K", Integer.valueOf(1));
- positive.put("R", Integer.valueOf(1));
- positive.put("E", Integer.valueOf(0));
- positive.put("Q", Integer.valueOf(0));
- positive.put("D", Integer.valueOf(0));
- positive.put("N", Integer.valueOf(0));
- positive.put("S", Integer.valueOf(0));
- positive.put("T", Integer.valueOf(0));
- positive.put("P", Integer.valueOf(0));
- positive.put("-", Integer.valueOf(1));
- positive.put("*", Integer.valueOf(1));
+ positive.put("I", ZERO);
+ positive.put("L", ZERO);
+ positive.put("V", ZERO);
+ positive.put("C", ZERO);
+ positive.put("A", ZERO);
+ positive.put("G", ZERO);
+ positive.put("M", ZERO);
+ positive.put("F", ZERO);
+ positive.put("Y", ZERO);
+ positive.put("W", ZERO);
+ positive.put("H", ONE);
+ positive.put("K", ONE);
+ positive.put("R", ONE);
+ positive.put("E", ZERO);
+ positive.put("Q", ZERO);
+ positive.put("D", ZERO);
+ positive.put("N", ZERO);
+ positive.put("S", ZERO);
+ positive.put("T", ZERO);
+ positive.put("P", ZERO);
+ positive.put("-", ONE);
+ positive.put("*", ONE);
}
static
{
- negative.put("I", Integer.valueOf(0));
- negative.put("L", Integer.valueOf(0));
- negative.put("V", Integer.valueOf(0));
- negative.put("C", Integer.valueOf(0));
- negative.put("A", Integer.valueOf(0));
- negative.put("G", Integer.valueOf(0));
- negative.put("M", Integer.valueOf(0));
- negative.put("F", Integer.valueOf(0));
- negative.put("Y", Integer.valueOf(0));
- negative.put("W", Integer.valueOf(0));
- negative.put("H", Integer.valueOf(0));
- negative.put("K", Integer.valueOf(0));
- negative.put("R", Integer.valueOf(0));
- negative.put("E", Integer.valueOf(1));
- negative.put("Q", Integer.valueOf(0));
- negative.put("D", Integer.valueOf(1));
- negative.put("N", Integer.valueOf(0));
- negative.put("S", Integer.valueOf(0));
- negative.put("T", Integer.valueOf(0));
- negative.put("P", Integer.valueOf(0));
- negative.put("-", Integer.valueOf(1));
- negative.put("*", Integer.valueOf(1));
+ negative.put("I", ZERO);
+ negative.put("L", ZERO);
+ negative.put("V", ZERO);
+ negative.put("C", ZERO);
+ negative.put("A", ZERO);
+ negative.put("G", ZERO);
+ negative.put("M", ZERO);
+ negative.put("F", ZERO);
+ negative.put("Y", ZERO);
+ negative.put("W", ZERO);
+ negative.put("H", ZERO);
+ negative.put("K", ZERO);
+ negative.put("R", ZERO);
+ negative.put("E", ONE);
+ negative.put("Q", ZERO);
+ negative.put("D", ONE);
+ negative.put("N", ZERO);
+ negative.put("S", ZERO);
+ negative.put("T", ZERO);
+ negative.put("P", ZERO);
+ negative.put("-", ONE);
+ negative.put("*", ONE);
}
static
{
- charged.put("I", Integer.valueOf(0));
- charged.put("L", Integer.valueOf(0));
- charged.put("V", Integer.valueOf(0));
- charged.put("C", Integer.valueOf(0));
- charged.put("A", Integer.valueOf(0));
- charged.put("G", Integer.valueOf(0));
- charged.put("M", Integer.valueOf(0));
- charged.put("F", Integer.valueOf(0));
- charged.put("Y", Integer.valueOf(0));
- charged.put("W", Integer.valueOf(0));
- charged.put("H", Integer.valueOf(1));
- charged.put("K", Integer.valueOf(1));
- charged.put("R", Integer.valueOf(1));
- charged.put("E", Integer.valueOf(1));
- charged.put("Q", Integer.valueOf(0));
- charged.put("D", Integer.valueOf(1));
- charged.put("N", Integer.valueOf(0)); // Asparagine is polar but not
+ charged.put("I", ZERO);
+ charged.put("L", ZERO);
+ charged.put("V", ZERO);
+ charged.put("C", ZERO);
+ charged.put("A", ZERO);
+ charged.put("G", ZERO);
+ charged.put("M", ZERO);
+ charged.put("F", ZERO);
+ charged.put("Y", ZERO);
+ charged.put("W", ZERO);
+ charged.put("H", ONE);
+ charged.put("K", ONE);
+ charged.put("R", ONE);
+ charged.put("E", ONE);
+ charged.put("Q", ZERO);
+ charged.put("D", ONE);
+ charged.put("N", ZERO); // Asparagine is polar but not
// charged.
// Alternative would be charged and
// negative (in basic form)?
- charged.put("S", Integer.valueOf(0));
- charged.put("T", Integer.valueOf(0));
- charged.put("P", Integer.valueOf(0));
- charged.put("-", Integer.valueOf(1));
- charged.put("*", Integer.valueOf(1));
+ charged.put("S", ZERO);
+ charged.put("T", ZERO);
+ charged.put("P", ZERO);
+ charged.put("-", ONE);
+ charged.put("*", ONE);
}
static
{
- aromatic.put("I", Integer.valueOf(0));
- aromatic.put("L", Integer.valueOf(0));
- aromatic.put("V", Integer.valueOf(0));
- aromatic.put("C", Integer.valueOf(0));
- aromatic.put("A", Integer.valueOf(0));
- aromatic.put("G", Integer.valueOf(0));
- aromatic.put("M", Integer.valueOf(0));
- aromatic.put("F", Integer.valueOf(1));
- aromatic.put("Y", Integer.valueOf(1));
- aromatic.put("W", Integer.valueOf(1));
- aromatic.put("H", Integer.valueOf(1));
- aromatic.put("K", Integer.valueOf(0));
- aromatic.put("R", Integer.valueOf(0));
- aromatic.put("E", Integer.valueOf(0));
- aromatic.put("Q", Integer.valueOf(0));
- aromatic.put("D", Integer.valueOf(0));
- aromatic.put("N", Integer.valueOf(0));
- aromatic.put("S", Integer.valueOf(0));
- aromatic.put("T", Integer.valueOf(0));
- aromatic.put("P", Integer.valueOf(0));
- aromatic.put("-", Integer.valueOf(1));
- aromatic.put("*", Integer.valueOf(1));
+ aromatic.put("I", ZERO);
+ aromatic.put("L", ZERO);
+ aromatic.put("V", ZERO);
+ aromatic.put("C", ZERO);
+ aromatic.put("A", ZERO);
+ aromatic.put("G", ZERO);
+ aromatic.put("M", ZERO);
+ aromatic.put("F", ONE);
+ aromatic.put("Y", ONE);
+ aromatic.put("W", ONE);
+ aromatic.put("H", ONE);
+ aromatic.put("K", ZERO);
+ aromatic.put("R", ZERO);
+ aromatic.put("E", ZERO);
+ aromatic.put("Q", ZERO);
+ aromatic.put("D", ZERO);
+ aromatic.put("N", ZERO);
+ aromatic.put("S", ZERO);
+ aromatic.put("T", ZERO);
+ aromatic.put("P", ZERO);
+ aromatic.put("-", ONE);
+ aromatic.put("*", ONE);
}
static
{
- aliphatic.put("I", Integer.valueOf(1));
- aliphatic.put("L", Integer.valueOf(1));
- aliphatic.put("V", Integer.valueOf(1));
- aliphatic.put("C", Integer.valueOf(0));
- aliphatic.put("A", Integer.valueOf(0));
- aliphatic.put("G", Integer.valueOf(0));
- aliphatic.put("M", Integer.valueOf(0));
- aliphatic.put("F", Integer.valueOf(0));
- aliphatic.put("Y", Integer.valueOf(0));
- aliphatic.put("W", Integer.valueOf(0));
- aliphatic.put("H", Integer.valueOf(0));
- aliphatic.put("K", Integer.valueOf(0));
- aliphatic.put("R", Integer.valueOf(0));
- aliphatic.put("E", Integer.valueOf(0));
- aliphatic.put("Q", Integer.valueOf(0));
- aliphatic.put("D", Integer.valueOf(0));
- aliphatic.put("N", Integer.valueOf(0));
- aliphatic.put("S", Integer.valueOf(0));
- aliphatic.put("T", Integer.valueOf(0));
- aliphatic.put("P", Integer.valueOf(0));
- aliphatic.put("-", Integer.valueOf(1));
- aliphatic.put("*", Integer.valueOf(1));
+ aliphatic.put("I", ONE);
+ aliphatic.put("L", ONE);
+ aliphatic.put("V", ONE);
+ aliphatic.put("C", ZERO);
+ aliphatic.put("A", ZERO);
+ aliphatic.put("G", ZERO);
+ aliphatic.put("M", ZERO);
+ aliphatic.put("F", ZERO);
+ aliphatic.put("Y", ZERO);
+ aliphatic.put("W", ZERO);
+ aliphatic.put("H", ZERO);
+ aliphatic.put("K", ZERO);
+ aliphatic.put("R", ZERO);
+ aliphatic.put("E", ZERO);
+ aliphatic.put("Q", ZERO);
+ aliphatic.put("D", ZERO);
+ aliphatic.put("N", ZERO);
+ aliphatic.put("S", ZERO);
+ aliphatic.put("T", ZERO);
+ aliphatic.put("P", ZERO);
+ aliphatic.put("-", ONE);
+ aliphatic.put("*", ONE);
}
static
{
- tiny.put("I", Integer.valueOf(0));
- tiny.put("L", Integer.valueOf(0));
- tiny.put("V", Integer.valueOf(0));
- tiny.put("C", Integer.valueOf(0));
- tiny.put("A", Integer.valueOf(1));
- tiny.put("G", Integer.valueOf(1));
- tiny.put("M", Integer.valueOf(0));
- tiny.put("F", Integer.valueOf(0));
- tiny.put("Y", Integer.valueOf(0));
- tiny.put("W", Integer.valueOf(0));
- tiny.put("H", Integer.valueOf(0));
- tiny.put("K", Integer.valueOf(0));
- tiny.put("R", Integer.valueOf(0));
- tiny.put("E", Integer.valueOf(0));
- tiny.put("Q", Integer.valueOf(0));
- tiny.put("D", Integer.valueOf(0));
- tiny.put("N", Integer.valueOf(0));
- tiny.put("S", Integer.valueOf(1));
- tiny.put("T", Integer.valueOf(0));
- tiny.put("P", Integer.valueOf(0));
- tiny.put("-", Integer.valueOf(1));
- tiny.put("*", Integer.valueOf(1));
+ tiny.put("I", ZERO);
+ tiny.put("L", ZERO);
+ tiny.put("V", ZERO);
+ tiny.put("C", ZERO);
+ tiny.put("A", ONE);
+ tiny.put("G", ONE);
+ tiny.put("M", ZERO);
+ tiny.put("F", ZERO);
+ tiny.put("Y", ZERO);
+ tiny.put("W", ZERO);
+ tiny.put("H", ZERO);
+ tiny.put("K", ZERO);
+ tiny.put("R", ZERO);
+ tiny.put("E", ZERO);
+ tiny.put("Q", ZERO);
+ tiny.put("D", ZERO);
+ tiny.put("N", ZERO);
+ tiny.put("S", ONE);
+ tiny.put("T", ZERO);
+ tiny.put("P", ZERO);
+ tiny.put("-", ONE);
+ tiny.put("*", ONE);
}
static
{
- proline.put("I", Integer.valueOf(0));
- proline.put("L", Integer.valueOf(0));
- proline.put("V", Integer.valueOf(0));
- proline.put("C", Integer.valueOf(0));
- proline.put("A", Integer.valueOf(0));
- proline.put("G", Integer.valueOf(0));
- proline.put("M", Integer.valueOf(0));
- proline.put("F", Integer.valueOf(0));
- proline.put("Y", Integer.valueOf(0));
- proline.put("W", Integer.valueOf(0));
- proline.put("H", Integer.valueOf(0));
- proline.put("K", Integer.valueOf(0));
- proline.put("R", Integer.valueOf(0));
- proline.put("E", Integer.valueOf(0));
- proline.put("Q", Integer.valueOf(0));
- proline.put("D", Integer.valueOf(0));
- proline.put("N", Integer.valueOf(0));
- proline.put("S", Integer.valueOf(0));
- proline.put("T", Integer.valueOf(0));
- proline.put("P", Integer.valueOf(1));
- proline.put("-", Integer.valueOf(1));
- proline.put("*", Integer.valueOf(1));
+ proline.put("I", ZERO);
+ proline.put("L", ZERO);
+ proline.put("V", ZERO);
+ proline.put("C", ZERO);
+ proline.put("A", ZERO);
+ proline.put("G", ZERO);
+ proline.put("M", ZERO);
+ proline.put("F", ZERO);
+ proline.put("Y", ZERO);
+ proline.put("W", ZERO);
+ proline.put("H", ZERO);
+ proline.put("K", ZERO);
+ proline.put("R", ZERO);
+ proline.put("E", ZERO);
+ proline.put("Q", ZERO);
+ proline.put("D", ZERO);
+ proline.put("N", ZERO);
+ proline.put("S", ZERO);
+ proline.put("T", ZERO);
+ proline.put("P", ONE);
+ proline.put("-", ONE);
+ proline.put("*", ONE);
}
static
HashSet<String> srcs = new HashSet<String>();
for (String src : sources)
{
- srcs.add(src);
+ srcs.add(src.toUpperCase());
}
List<DBRefEntry> res = new ArrayList<DBRefEntry>();
for (DBRefEntry dbr : dbrefs)
{
String source = getCanonicalName(dbr.getSource());
- if (srcs.contains(source))
+ if (srcs.contains(source.toUpperCase()))
{
res.add(dbr);
}
*/
package jalview.util;
+import java.util.Arrays;
+
/**
* DOCUMENT ME!
*
}
/**
- * DOCUMENT ME!
+ * Returns a string consisting of n repeats of character c
*
* @param c
- * DOCUMENT ME!
* @param n
- * DOCUMENT ME!
*
- * @return DOCUMENT ME!
+ * @return
*/
- private static String repeat(char c, int n)
+ static String repeat(char c, int n)
{
if (n <= 0)
{
return "";
}
-
- StringBuffer s = new StringBuffer(n);
-
- for (int i = 0; i < n; i++)
- {
- s.append(c);
- }
-
- return s.toString();
+ char[] chars = new char[n];
+ Arrays.fill(chars, c);
+ return new String(chars);
}
/**
*/
public static void appendPercentage(StringBuilder sb, float value, int dp)
{
- sb.append((int) value);
+ /*
+ * rounding first
+ */
+ double d = value;
+ long factor = 1L;
+ for (int i = 0; i < dp; i++)
+ {
+ factor *= 10;
+ }
+ d *= factor;
+ d += 0.5;
+
+ /*
+ * integer part
+ */
+ value = (float) (d / factor);
+ sb.append((long) value);
+
+ /*
+ * decimal places
+ */
if (dp > 0)
{
sb.append(".");
/*
* Sequence ID string
*/
- public static final String SEQUENCE_ID = "SEQUENCE_ID";
+ public static final String DB_ACCESSION = "DB_ACCESSION";
/*
* Sequence Name string
*/
- public static final String SEQUENCE_NAME = "SEQUENCE_NAME";
-
- /*
- * Default sequence URL link string for EMBL-EBI search
- */
- public static final String EMBLEBI_STRING = "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_NAME$";
+ public static final String SEQUENCE_ID = "SEQUENCE_ID";
/*
* Default sequence URL link string for EMBL-EBI search
*/
- public static final String OLD_EMBLEBI_STRING = "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$";
+ public static final String EMBLEBI_STRING = "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$";
/*
* Default sequence URL link string for SRS
*/
package jalview.util;
+import static jalview.util.UrlConstants.DB_ACCESSION;
import static jalview.util.UrlConstants.SEQUENCE_ID;
-import static jalview.util.UrlConstants.SEQUENCE_NAME;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.SequenceI;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
import java.util.Vector;
public class UrlLink
* Jalview 2.4 extension allows regular expressions to be used to parse ID
* strings and replace the result in the URL. Regex's operate on the whole ID
* string given to the matchURL method, if no regex is supplied, then only
- * text following the first pipe symbol will be susbstituted. Usage
+ * text following the first pipe symbol will be substituted. Usage
* documentation todo.
*/
- private String url_suffix, url_prefix, target, label, regexReplace;
+
+ // Internal constants
+ private static final String SEP = "|";
+
+ private static final String DELIM = "$";
+
+ private String urlSuffix;
+
+ private String urlPrefix;
+
+ private String target;
+
+ private String label;
+
+ private String regexReplace;
private boolean dynamic = false;
- private boolean uses_seq_id = false;
+ private boolean usesDBaccession = false;
private String invalidMessage = null;
/**
- * parse the given linkString of the form '<label>|<url>' into parts url may
+ * parse the given linkString of the form '<label>SEP<url>' into parts url may
* contain a string $SEQUENCE_ID<=optional regex=>$ where <=optional regex=>
* must be of the form =/<perl style regex>/=$
*
*/
public UrlLink(String link)
{
- int sep = link.indexOf("|");
- int psqid = link.indexOf("$" + SEQUENCE_ID);
- int nsqid = link.indexOf("$" + SEQUENCE_NAME);
+ int sep = link.indexOf(SEP);
+ int psqid = link.indexOf(DELIM + DB_ACCESSION);
+ int nsqid = link.indexOf(DELIM + SEQUENCE_ID);
if (psqid > -1)
{
dynamic = true;
- uses_seq_id = true;
+ usesDBaccession = true;
sep = parseTargetAndLabel(sep, psqid, link);
- parseUrl(link, SEQUENCE_ID, psqid, sep);
+ parseUrl(link, DB_ACCESSION, psqid, sep);
}
else if (nsqid > -1)
{
dynamic = true;
sep = parseTargetAndLabel(sep, nsqid, link);
- parseUrl(link, SEQUENCE_NAME, nsqid, sep);
+ parseUrl(link, SEQUENCE_ID, nsqid, sep);
}
else
{
target = link.substring(0, sep);
- sep = link.lastIndexOf("|");
+ sep = link.lastIndexOf(SEP);
label = link.substring(0, sep);
- url_prefix = link.substring(sep + 1);
+ urlPrefix = link.substring(sep + 1).trim();
regexReplace = null; // implies we trim any prefix if necessary //
- // regexReplace=".*\\|?(.*)";
- url_suffix = null;
+ urlSuffix = null;
}
label = label.trim();
target = target.trim();
- target = target.toUpperCase(); // DBRefEntry uppercases DB names
- // NB getCanonicalName might be better but does not currently change case
}
/**
*/
public String getUrl_suffix()
{
- return url_suffix;
+ return urlSuffix;
}
/**
*/
public String getUrl_prefix()
{
- return url_prefix;
+ return urlPrefix;
}
/**
}
/**
+ *
+ * @return whether link is dynamic
+ */
+ public boolean isDynamic()
+ {
+ return dynamic;
+ }
+
+ /**
+ *
+ * @return whether link uses DB Accession id
+ */
+ public boolean usesDBAccession()
+ {
+ return usesDBaccession;
+ }
+
+ /**
+ * Set the label
+ *
+ * @param newlabel
+ */
+ public void setLabel(String newlabel)
+ {
+ this.label = newlabel;
+ }
+
+ /**
* return one or more URL strings by applying regex to the given idstring
*
* @param idstring
{
// take whole regex
return new String[] { rg.stringMatched(),
- url_prefix + rg.stringMatched() + url_suffix };
+ urlPrefix + rg.stringMatched() + urlSuffix };
} /*
* else if (ns==1) { // take only subgroup match return new String[]
* { rg.stringMatched(1), url_prefix+rg.stringMatched(1)+url_suffix
if (mtch.length() > 0)
{
subs.addElement(mtch);
- subs.addElement(url_prefix + mtch + url_suffix);
+ subs.addElement(urlPrefix + mtch + urlSuffix);
}
s = r;
}
if (rg.matchedFrom(s) > -1)
{
subs.addElement(rg.stringMatched(s));
- subs.addElement(url_prefix + rg.stringMatched(s)
- + url_suffix);
+ subs.addElement(urlPrefix + rg.stringMatched(s)
+ + urlSuffix);
}
s++;
}
}
}
/* Otherwise - trim off any 'prefix' - pre 2.4 Jalview behaviour */
- if (idstring.indexOf("|") > -1)
+ if (idstring.indexOf(SEP) > -1)
{
- idstring = idstring.substring(idstring.lastIndexOf("|") + 1);
+ idstring = idstring.substring(idstring.lastIndexOf(SEP) + 1);
}
// just return simple url substitution.
- return new String[] { idstring, url_prefix + idstring + url_suffix };
+ return new String[] { idstring, urlPrefix + idstring + urlSuffix };
}
else
{
- return new String[] { "", url_prefix };
+ return new String[] { "", urlPrefix };
}
}
@Override
public String toString()
{
- String var = (uses_seq_id ? SEQUENCE_ID : SEQUENCE_NAME);
+ String var = (usesDBaccession ? DB_ACCESSION : SEQUENCE_ID);
return label
- + "|"
- + url_prefix
- + (dynamic ? ("$" + var + ((regexReplace != null) ? "="
- + regexReplace + "=$" : "$")) : "")
- + ((url_suffix == null) ? "" : url_suffix);
+ + SEP
+ + urlPrefix
+ + (dynamic ? (DELIM + var + ((regexReplace != null) ? "="
+ + regexReplace + "=" + DELIM : DELIM)) : "")
+ + ((urlSuffix == null) ? "" : urlSuffix);
}
/**
do
{
sep = p;
- p = link.indexOf("|", sep + 1);
+ p = link.indexOf(SEP, sep + 1);
} while (p > sep && p < psqid);
- // Assuming that the URL itself does not contain any '|' symbols
+ // Assuming that the URL itself does not contain any SEP symbols
// sep now contains last pipe symbol position prior to any regex symbols
label = link.substring(0, sep);
- if (label.indexOf("|") > -1)
+ if (label.indexOf(SEP) > -1)
{
- // | terminated database name / www target at start of Label
- target = label.substring(0, label.indexOf("|"));
+ // SEP terminated database name / www target at start of Label
+ target = label.substring(0, label.indexOf(SEP));
}
else if (label.indexOf(" ") > 2)
{
*/
protected void parseUrl(String link, String varName, int sqidPos, int sep)
{
- url_prefix = link.substring(sep + 1, sqidPos);
+ urlPrefix = link.substring(sep + 1, sqidPos).trim();
// delimiter at start of regex: e.g. $SEQUENCE_ID=/
- String startDelimiter = "$" + varName + "=/";
+ String startDelimiter = DELIM + varName + "=/";
// delimiter at end of regex: /=$
- String endDelimiter = "/=$";
+ String endDelimiter = "/=" + DELIM;
int startLength = startDelimiter.length();
&& (p > sqidPos + startLength))
{
// Extract Regex and suffix
- url_suffix = link.substring(p + endDelimiter.length());
+ urlSuffix = link.substring(p + endDelimiter.length());
regexReplace = link.substring(sqidPos + startLength, p);
try
{
// no regex
regexReplace = null;
// verify format is really correct.
- if (link.indexOf("$" + varName + "$") == sqidPos)
+ if (link.indexOf(DELIM + varName + DELIM) == sqidPos)
{
- url_suffix = link.substring(sqidPos + startLength - 1);
+ urlSuffix = link.substring(sqidPos + startLength - 1);
regexReplace = null;
}
else
}
}
+ /**
+ * Create a set of URL links for a sequence
+ *
+ * @param seq
+ * The sequence to create links for
+ * @param linkset
+ * Map of links: key = id + SEP + link, value = [target, label, id,
+ * link]
+ */
+ public void createLinksFromSeq(final SequenceI seq,
+ Map<String, List<String>> linkset)
+ {
+ if (seq != null && dynamic)
+ {
+ createDynamicLinks(seq, linkset);
+ }
+ else
+ {
+ createStaticLink(linkset);
+ }
+ }
+
+ /**
+ * Create a static URL link
+ *
+ * @param linkset
+ * Map of links: key = id + SEP + link, value = [target, label, id,
+ * link]
+ */
+ protected void createStaticLink(Map<String, List<String>> linkset)
+ {
+ if (!linkset.containsKey(label + SEP + getUrl_prefix()))
+ {
+ // Add a non-dynamic link
+ linkset.put(label + SEP + getUrl_prefix(),
+ Arrays.asList(target, label, null, getUrl_prefix()));
+ }
+ }
+
+ /**
+ * Create dynamic URL links
+ *
+ * @param seq
+ * The sequence to create links for
+ * @param linkset
+ * Map of links: key = id + SEP + link, value = [target, label, id,
+ * link]
+ */
+ protected void createDynamicLinks(final SequenceI seq,
+ Map<String, List<String>> linkset)
+ {
+ // collect id string too
+ String id = seq.getName();
+ String descr = seq.getDescription();
+ if (descr != null && descr.length() < 1)
+ {
+ descr = null;
+ }
+
+ if (usesDBAccession()) // link is ID
+ {
+ // collect matching db-refs
+ DBRefEntry[] dbr = DBRefUtils.selectRefs(seq.getDBRefs(),
+ new String[] { target });
+
+ // if there are any dbrefs which match up with the link
+ if (dbr != null)
+ {
+ for (int r = 0; r < dbr.length; r++)
+ {
+ // create Bare ID link for this URL
+ createBareURLLink(dbr[r].getAccessionId(), true, linkset);
+ }
+ }
+ }
+ else if (!usesDBAccession() && id != null) // link is name
+ {
+ // create Bare ID link for this URL
+ createBareURLLink(id, false, linkset);
+ }
+
+ // Create urls from description but only for URL links which are regex
+ // links
+ if (descr != null && getRegexReplace() != null)
+ {
+ // create link for this URL from description where regex matches
+ createBareURLLink(descr, false, linkset);
+ }
+ }
+
+ /*
+ * Create a bare URL Link
+ * Returns map where key = id + SEP + link, and value = [target, label, id, link]
+ */
+ protected void createBareURLLink(String id, Boolean combineLabel,
+ Map<String, List<String>> linkset)
+ {
+ String[] urls = makeUrls(id, true);
+ if (urls != null)
+ {
+ for (int u = 0; u < urls.length; u += 2)
+ {
+ if (!linkset.containsKey(urls[u] + SEP + urls[u + 1]))
+ {
+ String thisLabel = label;
+ if (combineLabel)
+ {
+ // incorporate label with idstring
+ thisLabel = label + SEP + urls[u];
+ }
+
+ linkset.put(urls[u] + SEP + urls[u + 1],
+ Arrays.asList(target, thisLabel, urls[u], urls[u + 1]));
+ }
+ }
+ }
+ }
+
private static void testUrls(UrlLink ul, String idstring, String[] urls)
{
* "PF3|http://us.expasy.org/cgi-bin/niceprot.pl?$SEQUENCE_ID=/PFAM:(.+)/=$"
* , "NOTFER|http://notfer.org/$SEQUENCE_ID=/(?<!\\s)(.+)/=$",
*/
- "NESTED|http://nested/$" + SEQUENCE_ID
+ "NESTED|http://nested/$" + DB_ACCESSION
+ "=/^(?:Label:)?(?:(?:gi\\|(\\d+))|([^:]+))/=$/nested" };
String[] idstrings = new String[] {
/*
}
}
}
-
- public boolean isDynamic()
- {
- // TODO Auto-generated method stub
- return dynamic;
- }
-
- public boolean usesSeqId()
- {
- return uses_seq_id;
- }
-
- public void setLabel(String newlabel)
- {
- this.label = newlabel;
- }
}
import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
import jalview.analysis.Conservation;
-import jalview.analysis.Profile;
import jalview.api.AlignCalcManagerI;
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.datamodel.CigarArray;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.HiddenSequences;
+import jalview.datamodel.ProfileI;
import jalview.datamodel.SearchResults;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceCollectionI;
/**
* results of alignment consensus analysis for visible portion of view
*/
- protected Profile[] hconsensus = null;
+ protected ProfileI[] hconsensus = null;
/**
* results of cDNA complement consensus visible portion of view
}
@Override
- public void setSequenceConsensusHash(Profile[] hconsensus)
+ public void setSequenceConsensusHash(ProfileI[] hconsensus)
{
this.hconsensus = hconsensus;
}
}
@Override
- public Profile[] getSequenceConsensusHash()
+ public ProfileI[] getSequenceConsensusHash()
{
return hconsensus;
}
cs.setConsensus(hconsensus);
if (cs.conservationApplied())
{
- cs.setConservation(Conservation.calculateConservation("All", 3,
+ cs.setConservation(Conservation.calculateConservation("All",
alignment.getSequences(), 0, alignment.getWidth(), false,
getConsPercGaps(), false));
}
package jalview.workers;
import jalview.analysis.AAFrequency;
-import jalview.analysis.Profile;
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.Annotation;
+import jalview.datamodel.ProfileI;
import jalview.datamodel.SequenceI;
import jalview.schemes.ColourSchemeI;
*/
protected void computeConsensus(AlignmentI alignment)
{
- Profile[] hconsensus = new Profile[alignment.getWidth()];
+ ProfileI[] hconsensus = new ProfileI[alignment.getWidth()];
SequenceI[] aseqs = getSequences();
AAFrequency.calculate(aseqs, 0, alignment.getWidth(), hconsensus, true);
/**
* @param hconsensus
*/
- protected void setColourSchemeConsensus(Profile[] hconsensus)
+ protected void setColourSchemeConsensus(ProfileI[] hconsensus)
{
ColourSchemeI globalColourScheme = alignViewport
.getGlobalColourScheme();
public void updateResultAnnotation(boolean immediate)
{
AlignmentAnnotation consensus = getConsensusAnnotation();
- Profile[] hconsensus = (Profile[]) getViewportConsensus();
+ ProfileI[] hconsensus = (ProfileI[]) getViewportConsensus();
if (immediate || !calcMan.isWorking(this) && consensus != null
&& hconsensus != null)
{
* the computed consensus data
*/
protected void deriveConsensus(AlignmentAnnotation consensusAnnotation,
- Profile[] hconsensus)
+ ProfileI[] hconsensus)
{
long nseq = getSequences().length;
AAFrequency.completeConsensus(consensusAnnotation, hconsensus, 0,
}
try
{
- cons = Conservation.calculateConservation("All", 3,
+ cons = Conservation.calculateConservation("All",
alignment.getSequences(), 0, alWidth - 1, false,
ConsPercGaps, quality != null);
} catch (IndexOutOfBoundsException x)
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.Annotation;
+import jalview.datamodel.ProfileI;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
SequenceI seq3 = new Sequence("Seq3", "C---G");
SequenceI seq4 = new Sequence("Seq4", "CA--t");
SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
- Profile[] result = new Profile[seq1.getLength()];
+ ProfileI[] result = new ProfileI[seq1.getLength()];
AAFrequency.calculate(seqs, 0, seq1.getLength(), result, false);
// col 0 is 100% C
- Profile col = result[0];
+ ProfileI col = result[0];
assertEquals(100f, col.getPercentageIdentity(false));
assertEquals(100f, col.getPercentageIdentity(true));
assertEquals(4, col.getMaxCount());
SequenceI seq3 = new Sequence("Seq3", "C--G");
SequenceI seq4 = new Sequence("Seq4", "CA-t");
SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
- Profile[] result = new Profile[seq1.getLength()];
+ ProfileI[] result = new ProfileI[seq1.getLength()];
AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true);
- Profile profile = result[0];
+ ProfileI profile = result[0];
assertEquals(4, profile.getCounts().getCount('C'));
assertEquals(4, profile.getHeight());
assertEquals(4, profile.getNonGapped());
SequenceI seq3 = new Sequence("Seq3", "C--G");
SequenceI seq4 = new Sequence("Seq4", "CA-t");
SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
- Profile[] result = new Profile[seq1.getLength()];
+ ProfileI[] result = new ProfileI[seq1.getLength()];
// ensure class loaded and initialized
AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true);
SequenceI seq3 = new Sequence("Seq3", "C---G");
SequenceI seq4 = new Sequence("Seq4", "CA--t");
SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
- Profile[] profiles = new Profile[seq1.getLength()];
+ ProfileI[] profiles = new ProfileI[seq1.getLength()];
AAFrequency.calculate(seqs, 0, seq1.getLength(), profiles, true);
AlignmentAnnotation consensus = new AlignmentAnnotation("Consensus",
SequenceI seq3 = new Sequence("Seq3", "C---G");
SequenceI seq4 = new Sequence("Seq4", "CA--t");
SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
- Profile[] profiles = new Profile[seq1.getLength()];
+ ProfileI[] profiles = new ProfileI[seq1.getLength()];
AAFrequency.calculate(seqs, 0, seq1.getLength(), profiles, true);
AlignmentAnnotation consensus = new AlignmentAnnotation("Consensus",
--- /dev/null
+package jalview.analysis;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.annotations.Test;
+
+public class ConservationTest
+{
+ @Test(groups = "Functional")
+ public void testRecordConservation()
+ {
+ Map<String, Integer> resultMap = new HashMap<String, Integer>();
+
+ // V is hydrophobic, aliphatic, small
+ Conservation.recordConservation(resultMap, "V");
+ assertEquals(resultMap.get("hydrophobic").intValue(), 1);
+ assertEquals(resultMap.get("aliphatic").intValue(), 1);
+ assertEquals(resultMap.get("small").intValue(), 1);
+ assertEquals(resultMap.get("tiny").intValue(), 0);
+ assertEquals(resultMap.get("polar").intValue(), 0);
+ assertEquals(resultMap.get("charged").intValue(), 0);
+
+ // now add S: not hydrophobic, small, tiny, polar, not aliphatic
+ Conservation.recordConservation(resultMap, "s");
+ assertEquals(resultMap.get("hydrophobic").intValue(), -1);
+ assertEquals(resultMap.get("aliphatic").intValue(), -1);
+ assertEquals(resultMap.get("small").intValue(), 1);
+ assertEquals(resultMap.get("tiny").intValue(), -1);
+ assertEquals(resultMap.get("polar").intValue(), -1);
+ assertEquals(resultMap.get("charged").intValue(), 0);
+ }
+
+ @Test(groups = "Functional")
+ public void testCountConservationAndGaps()
+ {
+ List<SequenceI> seqs = new ArrayList<SequenceI>();
+ seqs.add(new Sequence("seq1", "VGnY")); // not case sensitive
+ seqs.add(new Sequence("seq2", "-G-y"));
+ seqs.add(new Sequence("seq3", "VG-Y"));
+ seqs.add(new Sequence("seq4", "VGNW"));
+
+ Conservation cons = new Conservation("", seqs, 0, 50);
+ int[] counts = cons.countConservationAndGaps(0);
+ assertEquals(counts[0], 1); // conserved
+ assertEquals(counts[1], 1); // gap count
+ counts = cons.countConservationAndGaps(1);
+ assertEquals(counts[0], 1);
+ assertEquals(counts[1], 0);
+ counts = cons.countConservationAndGaps(2);
+ assertEquals(counts[0], 1);
+ assertEquals(counts[1], 2);
+ counts = cons.countConservationAndGaps(3);
+ assertEquals(counts[0], 0); // not conserved
+ assertEquals(counts[1], 0);
+ }
+
+ @Test(groups = "Functional")
+ public void testCalculate_noThreshold()
+ {
+ List<SequenceI> seqs = new ArrayList<SequenceI>();
+ seqs.add(new Sequence("seq1", "VGIV-N"));
+ seqs.add(new Sequence("seq2", "V-iL-N")); // not case sensitive
+ seqs.add(new Sequence("seq3", "V-IW-N"));
+ seqs.add(new Sequence("seq4", "VGLH-L"));
+
+ Conservation cons = new Conservation("", 0, seqs, 0, 5);
+ cons.calculate();
+
+ /*
+ * column 0: all V (hydrophobic/aliphatic/small)
+ */
+ Map<String, Integer> colCons = cons.total[0];
+ assertEquals(colCons.get("hydrophobic").intValue(), 1);
+ assertEquals(colCons.get("aliphatic").intValue(), 1);
+ assertEquals(colCons.get("small").intValue(), 1);
+ assertEquals(colCons.get("tiny").intValue(), 0);
+ assertEquals(colCons.get("proline").intValue(), 0);
+ assertEquals(colCons.get("charged").intValue(), 0);
+ assertEquals(colCons.get("negative").intValue(), 0);
+ assertEquals(colCons.get("polar").intValue(), 0);
+ assertEquals(colCons.get("positive").intValue(), 0);
+ assertEquals(colCons.get("aromatic").intValue(), 0);
+
+ /*
+ * column 1: all G (hydrophobic/small/tiny)
+ * gaps take default value of property present
+ */
+ colCons = cons.total[1];
+ assertEquals(colCons.get("hydrophobic").intValue(), 1);
+ assertEquals(colCons.get("aliphatic").intValue(), -1);
+ assertEquals(colCons.get("small").intValue(), 1);
+ assertEquals(colCons.get("tiny").intValue(), 1);
+ assertEquals(colCons.get("proline").intValue(), -1);
+ assertEquals(colCons.get("charged").intValue(), -1);
+ assertEquals(colCons.get("negative").intValue(), -1);
+ assertEquals(colCons.get("polar").intValue(), -1);
+ assertEquals(colCons.get("positive").intValue(), -1);
+ assertEquals(colCons.get("aromatic").intValue(), -1);
+
+ /*
+ * column 2: I/L (aliphatic/hydrophobic), all others negatively conserved
+ */
+ colCons = cons.total[2];
+ assertEquals(colCons.get("hydrophobic").intValue(), 1);
+ assertEquals(colCons.get("aliphatic").intValue(), 1);
+ assertEquals(colCons.get("small").intValue(), 0);
+ assertEquals(colCons.get("tiny").intValue(), 0);
+ assertEquals(colCons.get("proline").intValue(), 0);
+ assertEquals(colCons.get("charged").intValue(), 0);
+ assertEquals(colCons.get("negative").intValue(), 0);
+ assertEquals(colCons.get("polar").intValue(), 0);
+ assertEquals(colCons.get("positive").intValue(), 0);
+ assertEquals(colCons.get("aromatic").intValue(), 0);
+
+ /*
+ * column 3: VLWH all hydrophobic, none is tiny, negative or proline
+ */
+ colCons = cons.total[3];
+ assertEquals(colCons.get("hydrophobic").intValue(), 1);
+ assertEquals(colCons.get("aliphatic").intValue(), -1);
+ assertEquals(colCons.get("small").intValue(), -1);
+ assertEquals(colCons.get("tiny").intValue(), 0);
+ assertEquals(colCons.get("proline").intValue(), 0);
+ assertEquals(colCons.get("charged").intValue(), -1);
+ assertEquals(colCons.get("negative").intValue(), 0);
+ assertEquals(colCons.get("polar").intValue(), -1);
+ assertEquals(colCons.get("positive").intValue(), -1);
+ assertEquals(colCons.get("aromatic").intValue(), -1);
+
+ /*
+ * column 4: all gaps - counted as having all properties
+ */
+ colCons = cons.total[4];
+ assertEquals(colCons.get("hydrophobic").intValue(), 1);
+ assertEquals(colCons.get("aliphatic").intValue(), 1);
+ assertEquals(colCons.get("small").intValue(), 1);
+ assertEquals(colCons.get("tiny").intValue(), 1);
+ assertEquals(colCons.get("proline").intValue(), 1);
+ assertEquals(colCons.get("charged").intValue(), 1);
+ assertEquals(colCons.get("negative").intValue(), 1);
+ assertEquals(colCons.get("polar").intValue(), 1);
+ assertEquals(colCons.get("positive").intValue(), 1);
+ assertEquals(colCons.get("aromatic").intValue(), 1);
+
+ /*
+ * column 5: N (small polar) and L (aliphatic hydrophobic)
+ * have nothing in common!
+ */
+ colCons = cons.total[5];
+ assertEquals(colCons.get("hydrophobic").intValue(), -1);
+ assertEquals(colCons.get("aliphatic").intValue(), -1);
+ assertEquals(colCons.get("small").intValue(), -1);
+ assertEquals(colCons.get("tiny").intValue(), 0);
+ assertEquals(colCons.get("proline").intValue(), 0);
+ assertEquals(colCons.get("charged").intValue(), 0);
+ assertEquals(colCons.get("negative").intValue(), 0);
+ assertEquals(colCons.get("polar").intValue(), -1);
+ assertEquals(colCons.get("positive").intValue(), 0);
+ assertEquals(colCons.get("aromatic").intValue(), 0);
+ }
+
+ /**
+ * Test for the case whether the number of non-gapped sequences in a column
+ * has to be above a threshold
+ */
+ @Test(groups = "Functional")
+ public void testCalculate_threshold()
+ {
+ List<SequenceI> seqs = new ArrayList<SequenceI>();
+ seqs.add(new Sequence("seq1", "VGIV-"));
+ seqs.add(new Sequence("seq2", "V-iL-")); // not case sensitive
+ seqs.add(new Sequence("seq3", "V-IW-"));
+ seqs.add(new Sequence("seq4", "VGLH-"));
+ seqs.add(new Sequence("seq5", "VGLH-"));
+
+ /*
+ * threshold 50% means a residue has to occur 3 or more times
+ * in a column to be counted for conservation
+ */
+ // TODO: ConservationThread uses a value of 3
+ // calculateConservation states it is the minimum number of sequences
+ // but it is treated as percentage threshold in calculate() ?
+ Conservation cons = new Conservation("", 50, seqs, 0, 4);
+ cons.calculate();
+
+ /*
+ * column 0: all V (hydrophobic/aliphatic/small)
+ */
+ Map<String, Integer> colCons = cons.total[0];
+ assertEquals(colCons.get("hydrophobic").intValue(), 1);
+ assertEquals(colCons.get("aliphatic").intValue(), 1);
+ assertEquals(colCons.get("small").intValue(), 1);
+ assertEquals(colCons.get("tiny").intValue(), 0);
+ assertEquals(colCons.get("proline").intValue(), 0);
+ assertEquals(colCons.get("charged").intValue(), 0);
+ assertEquals(colCons.get("negative").intValue(), 0);
+ assertEquals(colCons.get("polar").intValue(), 0);
+ assertEquals(colCons.get("positive").intValue(), 0);
+ assertEquals(colCons.get("aromatic").intValue(), 0);
+
+ /*
+ * column 1: all G (hydrophobic/small/tiny)
+ * gaps are ignored as not above threshold
+ */
+ colCons = cons.total[1];
+ assertEquals(colCons.get("hydrophobic").intValue(), 1);
+ assertEquals(colCons.get("aliphatic").intValue(), 0);
+ assertEquals(colCons.get("small").intValue(), 1);
+ assertEquals(colCons.get("tiny").intValue(), 1);
+ assertEquals(colCons.get("proline").intValue(), 0);
+ assertEquals(colCons.get("charged").intValue(), 0);
+ assertEquals(colCons.get("negative").intValue(), 0);
+ assertEquals(colCons.get("polar").intValue(), 0);
+ assertEquals(colCons.get("positive").intValue(), 0);
+ assertEquals(colCons.get("aromatic").intValue(), 0);
+
+ /*
+ * column 2: I/L (aliphatic/hydrophobic), all others negatively conserved
+ */
+ colCons = cons.total[2];
+ assertEquals(colCons.get("hydrophobic").intValue(), 1);
+ assertEquals(colCons.get("aliphatic").intValue(), 1);
+ assertEquals(colCons.get("small").intValue(), 0);
+ assertEquals(colCons.get("tiny").intValue(), 0);
+ assertEquals(colCons.get("proline").intValue(), 0);
+ assertEquals(colCons.get("charged").intValue(), 0);
+ assertEquals(colCons.get("negative").intValue(), 0);
+ assertEquals(colCons.get("polar").intValue(), 0);
+ assertEquals(colCons.get("positive").intValue(), 0);
+ assertEquals(colCons.get("aromatic").intValue(), 0);
+
+ /*
+ * column 3: nothing above threshold
+ */
+ colCons = cons.total[3];
+ assertTrue(colCons.isEmpty());
+
+ /*
+ * column 4: all gaps - counted as having all properties
+ */
+ colCons = cons.total[4];
+ assertEquals(colCons.get("hydrophobic").intValue(), 1);
+ assertEquals(colCons.get("aliphatic").intValue(), 1);
+ assertEquals(colCons.get("small").intValue(), 1);
+ assertEquals(colCons.get("tiny").intValue(), 1);
+ assertEquals(colCons.get("proline").intValue(), 1);
+ assertEquals(colCons.get("charged").intValue(), 1);
+ assertEquals(colCons.get("negative").intValue(), 1);
+ assertEquals(colCons.get("polar").intValue(), 1);
+ assertEquals(colCons.get("positive").intValue(), 1);
+ assertEquals(colCons.get("aromatic").intValue(), 1);
+ }
+
+ /**
+ * Test the method that derives the conservation 'sequence' and the mouseover
+ * tooltips from the computed conservation
+ */
+ @Test(groups = "Functional")
+ public void testVerdict()
+ {
+ List<SequenceI> seqs = new ArrayList<SequenceI>();
+ seqs.add(new Sequence("seq1", "VGIVV-H"));
+ seqs.add(new Sequence("seq2", "VGILL-H"));
+ seqs.add(new Sequence("seq3", "VGIW--R"));
+ seqs.add(new Sequence("seq4", "VGLHH--"));
+ seqs.add(new Sequence("seq5", "VGLHH-R"));
+ seqs.add(new Sequence("seq6", "VGLHH--"));
+ seqs.add(new Sequence("seq7", "VGLHH-R"));
+ seqs.add(new Sequence("seq8", "VGLHH-R"));
+
+ // calculate with no threshold
+ Conservation cons = new Conservation("", 0, seqs, 0, 6);
+ cons.calculate();
+ // positive and negative conservation where <25% gaps in columns
+ cons.verdict(false, 25);
+
+ /*
+ * verify conservation 'sequence'
+ * cols 0 fully conserved and above threshold (*)
+ * col 2 properties fully conserved (+)
+ * col 3 VLWH 1 positively and 3 negatively conserved properties
+ * col 4 has 1 positively conserved property, but because gap contributes a
+ * 'positive' for all properties, no negative conservation is counted
+ * col 5 is all gaps
+ * col 6 has 25% gaps so fails threshold test
+ */
+ assertEquals(cons.getConsSequence().getSequenceAsString(), "**+41--");
+
+ /*
+ * verify tooltips; conserved properties are sorted alphabetically within
+ * positive followed by negative
+ */
+ assertEquals(
+ cons.getTooltip(0),
+ "aliphatic hydrophobic small !aromatic !charged !negative !polar !positive !proline !tiny");
+ assertEquals(
+ cons.getTooltip(1),
+ "hydrophobic small tiny !aliphatic !aromatic !charged !negative !polar !positive !proline");
+ assertEquals(
+ cons.getTooltip(2),
+ "aliphatic hydrophobic !aromatic !charged !negative !polar !positive !proline !small !tiny");
+ assertEquals(cons.getTooltip(3), "hydrophobic !negative !proline !tiny");
+ assertEquals(cons.getTooltip(4), "hydrophobic");
+ assertEquals(cons.getTooltip(5), "");
+ assertEquals(cons.getTooltip(6), "");
+ }
+}
-package jalview.analysis;
+package jalview.datamodel;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
-import jalview.analysis.ResidueCount.SymbolCounts;
+import jalview.datamodel.ResidueCount.SymbolCounts;
import org.junit.Assert;
import org.testng.annotations.Test;
}
rc.add('F');
+ /*
+ * percentages are rounded (0.5 rounded up)
+ * 10/40 9/40 7/40 6/40 1/40
+ */
assertEquals(rc.getTooltip(40, 0),
- "P 25%; W 22%; C 17%; Q 17%; K 15%; F 2%");
+ "P 25%; W 23%; C 18%; Q 18%; K 15%; F 3%");
+ rc.add('Q');
+ /*
+ * 10/30 9/30 8/30 7/30 6/30 1/30
+ */
assertEquals(rc.getTooltip(30, 1),
- "P 33.3%; W 30.0%; C 23.3%; Q 23.3%; K 20.0%; F 3.3%");
+ "P 33.3%; W 30.0%; Q 26.7%; C 23.3%; K 20.0%; F 3.3%");
}
@Test(groups = "Functional")
*/
package jalview.gui;
+import static jalview.util.UrlConstants.DB_ACCESSION;
+import static jalview.util.UrlConstants.SEQUENCE_ID;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
List<DBRefEntry> refs = new ArrayList<DBRefEntry>();
// links as might be added into Preferences | Connections dialog
- links.add("EMBL-EBI Search | http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_NAME$");
- links.add("UNIPROT | http://www.uniprot.org/uniprot/$SEQUENCE_ID$");
- links.add("INTERPRO | http://www.ebi.ac.uk/interpro/entry/$SEQUENCE_ID$");
+ links.add("EMBL-EBI Search | http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$"
+ + SEQUENCE_ID + "$");
+ links.add("UNIPROT | http://www.uniprot.org/uniprot/$" + DB_ACCESSION
+ + "$");
+ links.add("INTERPRO | http://www.ebi.ac.uk/interpro/entry/$"
+ + DB_ACCESSION + "$");
// Gene3D entry tests for case (in)sensitivity
- links.add("Gene3D | http://gene3d.biochem.ucl.ac.uk/Gene3D/search?sterm=$SEQUENCE_ID$&mode=protein");
+ links.add("Gene3D | http://gene3d.biochem.ucl.ac.uk/Gene3D/search?sterm=$"
+ + DB_ACCESSION + "$&mode=protein");
// make seq0 dbrefs
refs.add(new DBRefEntry(DBRefSource.UNIPROT, "1", "P83527"));
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
-import jalview.analysis.Profile;
+import jalview.datamodel.Profile;
+import jalview.datamodel.ProfileI;
import java.awt.Color;
* SR-T
* SR-T
*/
- Profile[] profiles = new Profile[4];
+ ProfileI[] profiles = new ProfileI[4];
profiles[0] = new Profile(4, 0, 2, "AS");
profiles[1] = new Profile(4, 0, 4, "R");
profiles[2] = new Profile(4, 4, 0, "");
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import org.testng.annotations.Test;
assertEquals('Q', ResidueProperties.getSingleCharacterCode("Gln"));
assertEquals('Q', ResidueProperties.getSingleCharacterCode("gln"));
}
+
+ @Test(groups = { "Functional" })
+ public void testPhysicoChemicalProperties()
+ {
+ checkProperty("aromatic", "FYWH-*");
+ checkProperty("aliphatic", "IVL-*");
+ checkProperty("tiny", "GAS-*");
+ checkProperty("small", "VCTGACSDNP-*");
+ checkProperty("charged", "HKRDE-*");
+ checkProperty("negative", "DE-*");
+ checkProperty("polar", "YWHRKTSNDEQ-*X");
+ checkProperty("positive", "HKR-*");
+ checkProperty("proline", "P-*");
+ checkProperty("hydrophobic", "MILVFYWHKCGAC-*X");
+ }
+
+ /**
+ * Verify that the residues in the list have the named property, and other
+ * residues do not
+ *
+ * @param property
+ * @param residues
+ */
+ void checkProperty(String property, String residues)
+ {
+ Map<String, Integer> props = ResidueProperties.propHash.get(property);
+
+ /*
+ * assert residues have the property (value 1 in lookup)
+ */
+ for (char res : residues.toCharArray())
+ {
+ assertEquals(res + " should be " + property, 1,
+ props.get(String.valueOf(res)).intValue());
+ }
+
+ /*
+ * assert other residues do not (value 0 in lookup)
+ */
+ for (String res : ResidueProperties.aa)
+ {
+ if (!residues.contains(res))
+ {
+ Integer propValue = props.get(String.valueOf(res));
+
+ if (propValue != null)
+ {
+ /*
+ * conservation calculation assigns unexpected symbols
+ * the same value as '-'; here we just check those which
+ * explicitly do not have the property
+ */
+ assertEquals(res + " should not be " + property, 0,
+ propValue.intValue());
+ }
+ }
+ }
+ }
}
assertSame(ref2, selected[0]);
assertSame(ref3, selected[1]);
- sources = new String[] { "Uniprot", "EMBLCDS" };
+ sources = new String[] { "EMBLCDS" };
selected = DBRefUtils.selectRefs(dbrefs, sources);
assertNull(selected);
+
+ sources = new String[] { "embl", "uniprot" };
+ selected = DBRefUtils.selectRefs(dbrefs, sources);
+ assertEquals(3, selected.length);
+ assertSame(ref1, selected[0]);
+ assertSame(ref2, selected[1]);
+ assertSame(ref3, selected[2]);
}
/**
public void testAppendPercentage()
{
StringBuilder sb = new StringBuilder();
- Format.appendPercentage(sb, 123.456f, 0);
+ Format.appendPercentage(sb, 123.436f, 0);
assertEquals(sb.toString(), "123");
sb.setLength(0);
- Format.appendPercentage(sb, 123.456f, 1);
+ Format.appendPercentage(sb, 123.536f, 0);
+ assertEquals(sb.toString(), "124");
+
+ sb.setLength(0);
+ Format.appendPercentage(sb, 799.536f, 0);
+ assertEquals(sb.toString(), "800");
+
+ sb.setLength(0);
+ Format.appendPercentage(sb, 123.436f, 1);
assertEquals(sb.toString(), "123.4");
sb.setLength(0);
- Format.appendPercentage(sb, 123.456f, 2);
- assertEquals(sb.toString(), "123.45");
+ Format.appendPercentage(sb, 123.436f, 2);
+ assertEquals(sb.toString(), "123.44");
sb.setLength(0);
- Format.appendPercentage(sb, 123.456f, 3);
- assertEquals(sb.toString(), "123.456");
+ Format.appendPercentage(sb, 123.436f, 3);
+ assertEquals(sb.toString(), "123.436");
sb.setLength(0);
- Format.appendPercentage(sb, 123.456f, 4);
- assertEquals(sb.toString(), "123.4560");
+ Format.appendPercentage(sb, 123.436f, 4);
+ assertEquals(sb.toString(), "123.4360");
+ }
+
+ @Test(groups = "Functional")
+ public void testForm_float()
+ {
+ Format f = new Format("%3.2f");
+ assertEquals(f.form(123f), "123.00");
+ assertEquals(f.form(123.1f), "123.10");
+ assertEquals(f.form(123.12f), "123.12");
+ assertEquals(f.form(123.124f), "123.12");
+ assertEquals(f.form(123.125f), "123.13");
+ assertEquals(f.form(123.126f), "123.13");
+
+ f = new Format("%3.0f");
+ assertEquals(f.form(123f), "123.");
+ assertEquals(f.form(12f), "12.");
+ assertEquals(f.form(123.4f), "123.");
+ assertEquals(f.form(123.5f), "124.");
+ assertEquals(f.form(123.6f), "124.");
+ assertEquals(f.form(129.6f), "130.");
+ }
+
+ @Test(groups = "Functional")
+ public void testRepeat()
+ {
+ assertEquals(Format.repeat('a', 3), "aaa");
+ assertEquals(Format.repeat('b', 0), "");
+ assertEquals(Format.repeat('c', -1), "");
}
}
*/
package jalview.util;
+import static jalview.util.UrlConstants.DB_ACCESSION;
import static jalview.util.UrlConstants.SEQUENCE_ID;
-import static jalview.util.UrlConstants.SEQUENCE_NAME;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertNull;
import static org.testng.AssertJUnit.assertTrue;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
+import jalview.datamodel.Sequence;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
import org.testng.annotations.Test;
public class UrlLinkTest
@Test(groups = { "Functional" })
public void testUrlLinkCreationNoRegex()
{
- // SEQUENCE_NAME
- UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_NAME
+ // SEQUENCE_ID
+ UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+ DELIM + URL_SUFFIX);
- assertEquals(DB.toUpperCase(), ul.getTarget());
+ assertEquals(DB, ul.getTarget());
assertEquals(DB, ul.getLabel());
assertEquals(URL_PREFIX, ul.getUrl_prefix());
assertEquals(URL_SUFFIX, ul.getUrl_suffix());
assertTrue(ul.isDynamic());
- assertFalse(ul.usesSeqId());
+ assertFalse(ul.usesDBAccession());
assertNull(ul.getRegexReplace());
assertTrue(ul.isValid());
assertNull(ul.getInvalidMessage());
- // SEQUENCE_ID
- ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID + DELIM
+ // DB_ACCESSION
+ ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION + DELIM
+ URL_SUFFIX);
- assertEquals(DB.toUpperCase(), ul.getTarget());
+ assertEquals(DB, ul.getTarget());
assertEquals(DB, ul.getLabel());
assertEquals(URL_PREFIX, ul.getUrl_prefix());
assertEquals(URL_SUFFIX, ul.getUrl_suffix());
assertTrue(ul.isDynamic());
- assertTrue(ul.usesSeqId());
+ assertTrue(ul.usesDBAccession());
assertNull(ul.getRegexReplace());
assertTrue(ul.isValid());
assertNull(ul.getInvalidMessage());
// Not dynamic
ul = new UrlLink(DB + SEP + URL_PREFIX + URL_SUFFIX.substring(1));
- assertEquals(DB.toUpperCase(), ul.getTarget());
+ assertEquals(DB, ul.getTarget());
assertEquals(DB, ul.getLabel());
assertEquals(URL_PREFIX + URL_SUFFIX.substring(1), ul.getUrl_prefix());
assertFalse(ul.isDynamic());
- assertFalse(ul.usesSeqId());
+ assertFalse(ul.usesDBAccession());
assertNull(ul.getRegexReplace());
assertTrue(ul.isValid());
assertNull(ul.getInvalidMessage());
@Test(groups = { "Functional" })
public void testUrlLinkCreationWithRegex()
{
- // SEQUENCE_NAME
- UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_NAME
+ // SEQUENCE_ID
+ UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+ REGEX_NESTED + DELIM + URL_SUFFIX);
- assertEquals(DB.toUpperCase(), ul.getTarget());
+ assertEquals(DB, ul.getTarget());
assertEquals(DB, ul.getLabel());
assertEquals(URL_PREFIX, ul.getUrl_prefix());
assertEquals(URL_SUFFIX, ul.getUrl_suffix());
assertTrue(ul.isDynamic());
- assertFalse(ul.usesSeqId());
+ assertFalse(ul.usesDBAccession());
assertEquals(REGEX_NESTED.substring(2, REGEX_NESTED.length() - 2),
ul.getRegexReplace());
assertTrue(ul.isValid());
assertNull(ul.getInvalidMessage());
- // SEQUENCE_ID
- ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+ // DB_ACCESSION
+ ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION
+ REGEX_NESTED + DELIM + URL_SUFFIX);
- assertEquals(DB.toUpperCase(), ul.getTarget());
+ assertEquals(DB, ul.getTarget());
assertEquals(DB, ul.getLabel());
assertEquals(URL_PREFIX, ul.getUrl_prefix());
assertEquals(URL_SUFFIX, ul.getUrl_suffix());
assertTrue(ul.isDynamic());
- assertTrue(ul.usesSeqId());
+ assertTrue(ul.usesDBAccession());
assertEquals(REGEX_NESTED.substring(2, REGEX_NESTED.length() - 2),
ul.getRegexReplace());
assertTrue(ul.isValid());
assertNull(ul.getInvalidMessage());
// invalid regex
- ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+ ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION
+ REGEX_RUBBISH + DELIM + URL_SUFFIX);
- assertEquals(DB.toUpperCase(), ul.getTarget());
+ assertEquals(DB, ul.getTarget());
assertEquals(DB, ul.getLabel());
assertEquals(URL_PREFIX, ul.getUrl_prefix());
assertEquals(URL_SUFFIX, ul.getUrl_suffix());
assertTrue(ul.isDynamic());
- assertTrue(ul.usesSeqId());
+ assertTrue(ul.usesDBAccession());
assertEquals(REGEX_RUBBISH.substring(2, REGEX_RUBBISH.length() - 2),
ul.getRegexReplace());
assertFalse(ul.isValid());
public void testMakeUrlNoRegex()
{
// Single non-regex
- UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_NAME
+ UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+ DELIM + URL_SUFFIX);
String idstring = "FER_CAPAA";
String[] urls = ul.makeUrls(idstring, true);
}
/**
- * Test construction of link by substituting sequence id or name
+ * Test construction of link by substituting sequence id or name using regular
+ * expression
*/
@Test(groups = { "Functional" })
public void testMakeUrlWithRegex()
{
// Unused regex
- UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+ UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION
+ REGEX_NESTED + DELIM + URL_SUFFIX);
String idstring = "FER_CAPAA";
String[] urls = ul.makeUrls(idstring, true);
assertNull(ul.getInvalidMessage());
}
+ /**
+ * Test creating links with null sequence
+ */
+ @Test(groups = { "Functional" })
+ public void testCreateLinksFromNullSequence()
+ {
+ UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+ + DELIM + URL_SUFFIX);
+
+ Map<String, List<String>> linkset = new LinkedHashMap<String, List<String>>();
+ ul.createLinksFromSeq(null, linkset);
+
+ String key = DB + SEP + URL_PREFIX;
+ assertEquals(1, linkset.size());
+ assertTrue(linkset.containsKey(key));
+ assertEquals(linkset.get(key).get(0), DB);
+ assertEquals(linkset.get(key).get(1), DB);
+ assertEquals(linkset.get(key).get(2), null);
+ assertEquals(linkset.get(key).get(3), URL_PREFIX);
+ }
+
+ /**
+ * Test creating links with non-dynamic urlLink
+ */
+ @Test(groups = { "Functional" })
+ public void testCreateLinksForNonDynamic()
+ {
+ UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + URL_SUFFIX);
+
+ Map<String, List<String>> linkset = new LinkedHashMap<String, List<String>>();
+ ul.createLinksFromSeq(null, linkset);
+
+ String key = DB + SEP + URL_PREFIX + URL_SUFFIX;
+ assertEquals(1, linkset.size());
+ assertTrue(linkset.containsKey(key));
+ assertEquals(linkset.get(key).get(0), DB);
+ assertEquals(linkset.get(key).get(1), DB);
+ assertEquals(linkset.get(key).get(2), null);
+ assertEquals(linkset.get(key).get(3), URL_PREFIX + URL_SUFFIX);
+ }
+
+ /**
+ * Test creating links
+ */
+ @Test(groups = { "Functional" })
+ public void testCreateLinksFromSequence()
+ {
+
+ // create list of links and list of DBRefs
+ List<String> links = new ArrayList<String>();
+ List<DBRefEntry> refs = new ArrayList<DBRefEntry>();
+
+ // links as might be added into Preferences | Connections dialog
+ links.add("EMBL-EBI Search | http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$"
+ + SEQUENCE_ID + "$");
+ links.add("UNIPROT | http://www.uniprot.org/uniprot/$" + DB_ACCESSION
+ + "$");
+ links.add("INTERPRO | http://www.ebi.ac.uk/interpro/entry/$"
+ + DB_ACCESSION + "$");
+
+ // make seq0 dbrefs
+ refs.add(new DBRefEntry(DBRefSource.UNIPROT, "1", "P83527"));
+ refs.add(new DBRefEntry("INTERPRO", "1", "IPR001041"));
+ refs.add(new DBRefEntry("INTERPRO", "1", "IPR006058"));
+ refs.add(new DBRefEntry("INTERPRO", "1", "IPR012675"));
+
+ Sequence seq0 = new Sequence("FER1", "AKPNGVL");
+
+ // add all the dbrefs to the sequence
+ seq0.addDBRef(refs.get(0));
+ seq0.addDBRef(refs.get(1));
+ seq0.addDBRef(refs.get(2));
+ seq0.addDBRef(refs.get(3));
+ seq0.createDatasetSequence();
+
+ // Test where link takes a sequence id as replacement
+ UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+ + DELIM + URL_SUFFIX);
+
+ Map<String, List<String>> linkset = new LinkedHashMap<String, List<String>>();
+ ul.createLinksFromSeq(seq0, linkset);
+
+ String key = seq0.getName() + SEP + URL_PREFIX + seq0.getName()
+ + URL_SUFFIX;
+ assertEquals(1, linkset.size());
+ assertTrue(linkset.containsKey(key));
+ assertEquals(linkset.get(key).get(0), DB);
+ assertEquals(linkset.get(key).get(1), DB);
+ assertEquals(linkset.get(key).get(2), seq0.getName());
+ assertEquals(linkset.get(key).get(3), URL_PREFIX + seq0.getName()
+ + URL_SUFFIX);
+
+ // Test where link takes a db annotation id and only has one dbref
+ ul = new UrlLink(links.get(1));
+ linkset = new LinkedHashMap<String, List<String>>();
+ ul.createLinksFromSeq(seq0, linkset);
+
+ key = "P83527|http://www.uniprot.org/uniprot/P83527";
+ assertEquals(1, linkset.size());
+ assertTrue(linkset.containsKey(key));
+ assertEquals(linkset.get(key).get(0), DBRefSource.UNIPROT);
+ assertEquals(linkset.get(key).get(1), DBRefSource.UNIPROT + SEP
+ + "P83527");
+ assertEquals(linkset.get(key).get(2), "P83527");
+ assertEquals(linkset.get(key).get(3),
+ "http://www.uniprot.org/uniprot/P83527");
+
+ // Test where link takes a db annotation id and has multiple dbrefs
+ ul = new UrlLink(links.get(2));
+ linkset = new LinkedHashMap<String, List<String>>();
+ ul.createLinksFromSeq(seq0, linkset);
+ assertEquals(3, linkset.size());
+
+ // check each link made it in correctly
+ key = "IPR001041|http://www.ebi.ac.uk/interpro/entry/IPR001041";
+ assertTrue(linkset.containsKey(key));
+ assertEquals(linkset.get(key).get(0), "INTERPRO");
+ assertEquals(linkset.get(key).get(1), "INTERPRO" + SEP + "IPR001041");
+ assertEquals(linkset.get(key).get(2), "IPR001041");
+ assertEquals(linkset.get(key).get(3),
+ "http://www.ebi.ac.uk/interpro/entry/IPR001041");
+
+ key = "IPR006058|http://www.ebi.ac.uk/interpro/entry/IPR006058";
+ assertTrue(linkset.containsKey(key));
+ assertEquals(linkset.get(key).get(0), "INTERPRO");
+ assertEquals(linkset.get(key).get(1), "INTERPRO" + SEP + "IPR006058");
+ assertEquals(linkset.get(key).get(2), "IPR006058");
+ assertEquals(linkset.get(key).get(3),
+ "http://www.ebi.ac.uk/interpro/entry/IPR006058");
+
+ key = "IPR012675|http://www.ebi.ac.uk/interpro/entry/IPR012675";
+ assertTrue(linkset.containsKey(key));
+ assertEquals(linkset.get(key).get(0), "INTERPRO");
+ assertEquals(linkset.get(key).get(1), "INTERPRO" + SEP + "IPR012675");
+ assertEquals(linkset.get(key).get(2), "IPR012675");
+ assertEquals(linkset.get(key).get(3),
+ "http://www.ebi.ac.uk/interpro/entry/IPR012675");
+
+ // Test where there are no matching dbrefs for the link
+ ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION + DELIM
+ + URL_SUFFIX);
+ linkset = new LinkedHashMap<String, List<String>>();
+ ul.createLinksFromSeq(seq0, linkset);
+ assertTrue(linkset.isEmpty());
+ }
+
}