AlignmentAnnotation aa;
+ // 0 - normalised dot product
+ // 1 - L1 - ie (abs(v_1-v_2)/dim(v))
+ // L1 is more rational - since can reason about value of difference,
+ // normalised dot product might give cleaner clusters, but more difficult to
+ // understand.
+
+ int mode = 1;
+
/**
* compute cosine distance matrix for a given contact matrix and create a
* UPGMA tree
- *
* @param cm
+ * @param cosineOrDifference false - dot product : true - L1
*/
public AverageDistanceEngine(AlignmentViewport av, AlignmentAnnotation aa,
- ContactMatrixI cm)
+ ContactMatrixI cm, boolean cosineOrDifference)
{
this.av = av;
this.aa = aa;
this.cm = cm;
+ mode = (cosineOrDifference) ? 1 :0;
calculate(cm);
}
- // 0 - normalised dot product
- // 1 - L1 - ie (abs(v_1-v_2)/dim(v))
- // L1 is more rational - since can reason about value of difference,
- // normalised dot product might give cleaner clusters, but more difficult to
- // understand.
-
- int mode = 1;
public void calculate(ContactMatrixI cm)
{
{
from_column = 0;
}
- if (to_column > getContactHeight())
+ if (to_column >= getContactHeight())
{
- to_column = getContactHeight();
+ to_column = getContactHeight()-1;
}
ContactRange cr = new ContactRange();
cr.setFrom_column(from_column);
import java.util.BitSet;
import java.util.List;
+import jalview.util.ColorUtils;
+import jalview.ws.datamodel.MappableContactMatrixI;
+
public interface ContactMatrixI
{
}
void setGroupSet(GroupSet makeGroups);
+
+ default void randomlyReColourGroups() {
+ if (hasGroupSet())
+ {
+ GroupSetI groups = getGroupSet();
+ for (BitSet group:groups.getGroups())
+ {
+ groups.setColorForGroup(group, ColorUtils.getARandomColor());
+ }
+ }
+ }
+
+ default void transferGroupColorsTo(AlignmentAnnotation aa)
+ {
+ if (hasGroupSet())
+ {
+ GroupSetI groups = getGroupSet();
+ // stash colors in linked annotation row.
+ // doesn't work yet. TESTS!
+ int sstart = aa.sequenceRef != null ? aa.sequenceRef.getStart() - 1
+ : 0;
+ Annotation ae;
+ Color gpcol = null;
+ int[] seqpos = null;
+ for (BitSet gp : groups.getGroups())
+ {
+ gpcol = groups.getColourForGroup(gp);
+ for (int p = gp.nextSetBit(0); p >= 0
+ && p < Integer.MAX_VALUE; p = gp.nextSetBit(p + 1))
+ {
+ if (this instanceof MappableContactMatrixI)
+ {
+ MappableContactMatrixI mcm = (MappableContactMatrixI) this;
+ seqpos = mcm.getMappedPositionsFor(aa.sequenceRef, p);
+ if (seqpos == null)
+ {
+ // no mapping for this column.
+ continue;
+ }
+ // TODO: handle ranges...
+ ae = aa.getAnnotationForPosition(seqpos[0]);
+ }
+ else
+ {
+ ae = aa.getAnnotationForPosition(p + sstart);
+ }
+ if (ae != null)
+ {
+ ae.colour = gpcol.brighter().darker();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * look up the colour for a column in the associated contact matrix
+ * @return Color.white or assigned colour
+ */
+ default Color getGroupColorForPosition(int column)
+ {
+ if (hasGroupSet())
+ {
+ GroupSetI groups = getGroupSet();
+ for (BitSet gp:groups.getGroups())
+ {
+ if (gp.get(column))
+ {
+ return groups.getColourForGroup(gp);
+ }
+ }
+ }
+ return Color.white;
+ }
+
}
return treeType;
}
- public static GroupSet makeGroups(ContactMatrixI matrix, float thresh,
+ public static GroupSet makeGroups(ContactMatrixI matrix, boolean autoCut)
+ {
+ return makeGroups(matrix, autoCut, 0, autoCut);
+ }
+ public static GroupSet makeGroups(ContactMatrixI matrix, boolean auto, float thresh,
boolean abs)
{
AverageDistanceEngine clusterer = new AverageDistanceEngine(null, null,
- matrix);
+ matrix, true);
double height = clusterer.findHeight(clusterer.getTopNode());
+ Console.debug("Column tree height: " + height);
String newick = new jalview.io.NewickFile(clusterer.getTopNode(), false,
true).print();
String treeType = "UPGMA";
Console.trace("Newick string\n" + newick);
List<BinaryNode> nodegroups;
- if (abs ? height > thresh : 0 < thresh && thresh < 1)
+ float cut = -1f;
+ if (auto)
{
- float cut = abs ? (float) (thresh / height) : thresh;
- Console.debug("Threshold " + cut + " for height=" + height);
-
- nodegroups = clusterer.groupNodes(cut);
+ double rootw = 0;
+ int p = 2;
+ BinaryNode bn = clusterer.getTopNode();
+ while (p-- > 0 & bn.left() != null)
+ {
+ if (bn.left() != null)
+ {
+ bn = bn.left();
+ }
+ if (bn.left() != null)
+ {
+ rootw = bn.height;
+ }
+ }
+ thresh = Math.max((float) (rootw / height) - 0.01f, 0);
+ cut = thresh;
+ nodegroups = clusterer.groupNodes(thresh);
}
else
{
- nodegroups = new ArrayList<BinaryNode>();
- nodegroups.add(clusterer.getTopNode());
+ if (abs ? (height > thresh) : (0 < thresh && thresh < 1))
+ {
+ cut = abs ? thresh : (float) (thresh * height);
+ Console.debug("Threshold " + cut + " for height=" + height);
+ nodegroups = clusterer.groupNodes(cut);
+ }
+ else
+ {
+ nodegroups = new ArrayList<BinaryNode>();
+ nodegroups.add(clusterer.getTopNode());
+ }
}
+
List<BitSet> groups = new ArrayList<>();
for (BinaryNode root : nodegroups)
{
}
groups.add(gpset);
}
- GroupSet grps = new GroupSet(abs, thresh, groups, treeType, newick);
+ GroupSet grps = new GroupSet(abs, (cut == -1f) ? thresh : cut, groups,
+ treeType, newick);
return grps;
}
{
NewickFile fin = new NewickFile(
new FileParse(cm.getNewick(), DataSourceType.PASTE));
- String title = cm.getAnnotLabel() + " " + cm.getTreeMethod() + " tree"
- + aa.sequenceRef != null
+ String title = aa.label + " "
+ + cm.getTreeMethod() + " tree" + (aa.sequenceRef != null
? (" for " + aa.sequenceRef.getDisplayId(false))
- : "";
+ : "");
showColumnWiseTree(fin, aa, title, w, h, x, y);
} catch (Throwable xx)
{
return null;
}
- TreePanel tp = new TreePanel(alignPanel, nf, aa, title);
+ TreePanel tp = new TreePanel(alignPanel, nf, aa, treeTitle);
tp.setSize(w, h);
tp.setLocation(x, y);
}
- Desktop.addInternalFrame(tp, title, w, h);
+ Desktop.addInternalFrame(tp, treeTitle, w, h);
return tp;
} catch (Throwable xx)
{
public void actionPerformed(ActionEvent e)
{
sel_row.setShowGroupsForContactMatrix(chitem.getState());
- ap.getAnnotationPanel()
- .paint(ap.getAnnotationPanel().getGraphics());
+ // so any annotation colour changes are propagated - though they
+ // probably won't be unless the annotation row colours are removed
+ // too!
+ ap.alignmentChanged();
}
});
pop.add(chitem);
"action.clustering_matrix_for",
cm.getAnnotDescr(), 5f),
progBar = System.currentTimeMillis());
- cm.setGroupSet(GroupSet.makeGroups(cm, 5f, true));
+ cm.setGroupSet(GroupSet.makeGroups(cm, true));
+ cm.randomlyReColourGroups();
+ cm.transferGroupColorsTo(alignmentAnnotation);
+ ap.alignmentChanged();
ap.alignFrame.showContactMapTree(alignmentAnnotation, cm);
ap.alignFrame.setProgressBar(null, progBar);
}
if (evt.isControlDown()
&& PAEContactMatrix.PAEMATRIX.equals(clicked.getCalcId()))
{
- int c = fr - 1;
+ int c = fr;
ContactRange cr = forCurrentX.getRangeFor(fr, to);
double cval;
// TODO: could use GraphLine instead of arbitrary picking
// controls feathering - what other elements in row/column
// should we select
double thresh = cr.getMean() + (cr.getMax() - cr.getMean()) * .15;
- while (c > 0)
+ while (c >= 0)
{
cval = forCurrentX.getContactAt(c);
if (// cr.getMin() <= cval &&
ContactGeometry lastXcgeom = new ContactGeometry(forFromX,
cma.graphHeight);
ContactGeometry.contactInterval lastXci = lastXcgeom
- .mapFor(rowIndex[1], rowIndex[1] - deltaY);
+ .mapFor(rowIndex[1], rowIndex[1] + deltaY);
ContactGeometry cXcgeom = new ContactGeometry(forToX,
cma.graphHeight);
ContactGeometry.contactInterval cXci = cXcgeom.mapFor(rowIndex[1],
- rowIndex[1] - deltaY);
+ rowIndex[1] + deltaY);
// mark rectangular region formed by drag
jalview.bin.Console.trace("Matrix Selection from last(" + fromXc
{
row = i;
res[0] = row;
- res[1] = height - yPos;
+ res[1] = yPos-lheight;
break;
}
}
// TODO abstract tooltip generator so different implementations can be built
if (ann.graph == AlignmentAnnotation.CONTACT_MAP)
{
+ if (rowAndOffset>=ann.graphHeight)
+ {
+ return null;
+ }
ContactListI clist = av.getContactList(ann, column);
if (clist != null)
{
import jalview.analysis.Conservation;
import jalview.analysis.TreeModel;
import jalview.api.AlignViewportI;
+import jalview.bin.Console;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.Annotation;
import jalview.datamodel.BinaryNode;
import jalview.gui.JalviewColourChooser.ColourChooserListener;
import jalview.schemes.ColourSchemeI;
import jalview.structure.SelectionSource;
+import jalview.util.ColorUtils;
import jalview.util.Format;
import jalview.util.MessageManager;
import jalview.ws.datamodel.MappableContactMatrixI;
boolean has_placeholders = false;
longestName = "";
+ AlignmentAnnotation aa = tp.getAssocAnnotation();
+ ContactMatrixI cm = (aa!=null) ? av.getContactMatrix(aa) : null;
+ if (cm!=null && cm.hasCutHeight())
+ {
+ threshold=(float) cm.getCutHeight();
+ }
+
for (int i = 0; i < leaves.size(); i++)
{
BinaryNode lf = leaves.elementAt(i);
longestName = TreeCanvas.PLACEHOLDER
+ ((Sequence) lf.element()).getName();
}
+ if (tp.isColumnWise() && cm!=null)
+ {
+ // get color from group colours, if they are set for the matrix
+ try {
+ Color col = cm.getGroupColorForPosition(parseColumnNode(lf));
+ setColor(lf,col.brighter());
+ } catch (NumberFormatException ex) {};
+ }
}
setMarkPlaceholders(has_placeholders);
* @param offy
* DOCUMENT ME!
*/
- public void drawNode(Graphics g, BinaryNode node, float chunk,
+ public void drawNode(Graphics g, BinaryNode node, double chunk,
double wscale, int width, int offx, int offy)
{
if (node == null)
+ ((BinaryNode) top.right()).count;
}
- float chunk = (float) (height - (offy)) / top.count;
+ double chunk = (double) (height - (offy)) / (double)top.count;
drawNode(g2, tree.getTopNode(), chunk, wscale, width, offx, offy);
threshold = 0f;
}
}
-
+ Console.log.debug("Tree cut threshold set at:" + threshold);
PaintRefresher.Refresh(tp,
getAssociatedPanel().av.getSequenceSetId());
repaint();
Map<BitSet, Color> colors = new HashMap();
for (int i = 0; i < groups.size(); i++)
{
- Color col = new Color((int) (Math.random() * 255),
- (int) (Math.random() * 255), (int) (Math.random() * 255));
+ Color col = ColorUtils.getARandomColor();
+
setColor(groups.get(i), col.brighter());
Vector<BinaryNode> l = tree.findLeaves(groups.get(i));
cm.setColorForGroup(gp, colors.get(gp));
}
}
- // stash colors in linked annotation row.
- // doesn't work yet. TESTS!
- int sstart = aa.sequenceRef != null ? aa.sequenceRef.getStart() - 1
- : 0;
- Annotation ae;
- Color gpcol = null;
- int[] seqpos = null;
- for (BitSet gp : colors.keySet())
- {
- gpcol = colors.get(gp);
- for (int p = gp.nextSetBit(0); p >= 0
- && p < Integer.MAX_VALUE; p = gp.nextSetBit(p + 1))
- {
- if (cm instanceof MappableContactMatrixI)
- {
- MappableContactMatrixI mcm = (MappableContactMatrixI) cm;
- seqpos = mcm.getMappedPositionsFor(aa.sequenceRef, p);
- if (seqpos == null)
- {
- // no mapping for this column.
- continue;
- }
- // TODO: handle ranges...
- ae = aa.getAnnotationForPosition(seqpos[0]);
- }
- else
- {
- ae = aa.getAnnotationForPosition(p + sstart);
- }
- if (ae != null)
- {
- ae.colour = gpcol.brighter().darker();
- }
- }
- }
+ cm.transferGroupColorsTo(aa);
}
}
}
}
}
-
+ private int parseColumnNode(BinaryNode bn) throws NumberFormatException
+ {
+ return Integer.parseInt(
+ bn.getName().substring(bn.getName().indexOf("c") + 1));
+ }
private boolean isColumnForNodeSelected(BinaryNode bn)
{
SequenceI rseq = tp.assocAnnotation.sequenceRef;
int colm = -1;
try
{
- colm = Integer.parseInt(
- bn.getName().substring(bn.getName().indexOf("c") + 1));
+ colm = parseColumnNode(bn);
} catch (Exception e)
{
return false;
// parse out from nodename
try
{
- colm = Integer.parseInt(
- bn.getName().substring(bn.getName().indexOf("c") + 1));
+ colm = parseColumnNode(bn);
} catch (Exception e)
{
continue;
if (mcm!=null)
{
int[] seqpos = mcm.getMappedPositionsFor(
- tp.assocAnnotation.sequenceRef, colm);
+ rseq, colm);
if (seqpos == null)
{
// no mapping for this column.
continue;
}
// TODO: handle ranges...
- offp = seqpos[0]-1;
+ offp = rseq.findIndex(seqpos[0])-1;
}
else
{
this.treeType = type;
this.scoreModelName = modelName;
+ treeCanvas = new TreeCanvas(this, ap, scrollPane);
+ scrollPane.setViewportView(treeCanvas);
+
if (columnWise)
{
bootstrapMenu.setVisible(false);
- placeholdersMenu.setSelected(false);
+ placeholdersMenu.setState(false);
placeholdersMenu.setVisible(false);
- fitToWindow.setSelected(false);
+ fitToWindow.setState(false);
sortAssocViews.setVisible(false);
}
- treeCanvas = new TreeCanvas(this, ap, scrollPane);
- scrollPane.setViewportView(treeCanvas);
addKeyListener(new KeyAdapter()
{
? new NJTree(av, sm, similarityParams)
: new AverageDistanceTree(av, sm, similarityParams);
tree = new TreeModel(njtree);
- showDistances(true);
+ // don't display distances for columnwise trees
}
-
+ showDistances(!columnWise);
tree.reCount(tree.getTopNode());
tree.findHeight(tree.getTopNode());
treeCanvas.setTree(tree);
}
eRes = Math.min(eRes, aa_annotations.length);
- int x = 0, y2 = y;
+ int x = 0, topY = y;
- g.setColor(shade.no_data);
-
- g.drawLine(x, y2, (eRes - sRes) * charWidth, y2);
+ // uncomment below to render whole area of matrix as pink
+ // g.setColor(shade.no_data);
+ // g.fillRect(x, topY-_aa.height, (eRes - sRes) * charWidth, _aa.graphHeight);
+
boolean showGroups = _aa.isShowGroupsForContactMatrix();
int column;
int aaMax = aa_annotations.length - 1;
final ContactGeometry cgeom = new ContactGeometry(contacts,
_aa.graphHeight);
- for (int ht = y2, eht = y2
- - _aa.graphHeight; ht >= eht; ht -= cgeom.pixels_step)
+ for (int ht = 0, botY = topY
+ - _aa.height; ht < _aa.graphHeight; ht += cgeom.pixels_step)
{
- ContactGeometry.contactInterval ci = cgeom.mapFor(y2 - ht,
- y2 - ht + cgeom.pixels_step);
+ ContactGeometry.contactInterval ci = cgeom.mapFor(ht,
+ ht + cgeom.pixels_step);
// cstart = (int) Math.floor(((double) y2 - ht) * contacts_per_pixel);
// cend = (int) Math.min(contact_height,
// Math.ceil(cstart + contacts_per_pixel * pixels_step));
g.setColor(col);
if (cgeom.pixels_step > 1)
{
- g.fillRect(x * charWidth, ht, charWidth, 1 + cgeom.pixels_step);
+ g.fillRect(x * charWidth, botY+ht, charWidth, 1 + cgeom.pixels_step);
}
else
{
- g.drawLine(x * charWidth, ht, (x + 1) * charWidth, ht);
+ g.drawLine(x * charWidth, botY+ht, (x + 1) * charWidth, botY+ht);
}
}
x++;
return color;
}
+
+ /**
+ *
+ * @return random color
+ */
+ public static final Color getARandomColor()
+ {
+ Color col = new Color((int) (Math.random() * 255),
+ (int) (Math.random() * 255), (int) (Math.random() * 255));
+ return col;
+ }
/**
* Convert to Tk colour code format
*
if (aa.graph > 0)
{
- aa.height += aa.graphHeight;
+ aa.height += aa.graphHeight+20;
}
if (aa.height == 0)
import jalview.util.MapUtils;
import jalview.ws.dbsources.EBIAlfaFold;
+/**
+ * routines and class for holding predicted alignment error matrices as produced
+ * by alphafold et al.
+ *
+ * getContactList(column) returns the vector of predicted alignment errors for
+ * reference position given by column getElementAt(column, i) returns the
+ * predicted superposition error for the ith position when column is used as
+ * reference
+ *
+ * Many thanks to Ora Schueler Furman for noticing that earlier development
+ * versions did not show the PAE oriented correctly
+ *
+ * @author jprocter
+ *
+ */
public class PAEContactMatrix extends
MappableContactMatrix<PAEContactMatrix> implements ContactMatrixI
{
Object d = scores.next();
if (d instanceof Double)
{
- elements[row][col++] = ((Double) d).longValue();
+ elements[col][row] = ((Double) d).longValue();
}
else
{
- elements[row][col++] = (float) ((Long) d).longValue();
+ elements[col][row] = (float) ((Long) d).longValue();
}
- if (maxscore < elements[row][col - 1])
+ if (maxscore < elements[col][row])
{
- maxscore = elements[row][col - 1];
+ maxscore = elements[col][row];
}
+ col++;
}
row++;
col = 0;
cols = ((List<Long>) pae_obj.get("residue2")).iterator();
Iterator<Double> scores = ((List<Double>) pae_obj.get("distance"))
.iterator();
- elements = new float[maxrow][maxcol];
+ elements = new float[maxcol][maxrow];
while (scores.hasNext())
{
float escore = scores.next().floatValue();
{
maxcol = col;
}
- elements[row - 1][col - 1] = escore;
+ elements[col - 1][row-1] = escore;
}
maxscore = ((Double) MapUtils.getFirst(pae_obj,
"max_predicted_aligned_error", "max_pae")).floatValue();
}
+ /**
+ * getContactList(column) @returns the vector of predicted alignment errors
+ * for reference position given by column
+ */
@Override
public ContactListI getContactList(final int column)
{
});
}
+ /**
+ * getElementAt(column, i) @returns the predicted superposition error for the
+ * ith position when column is used as reference
+ */
@Override
protected double getElementAt(int _column, int i)
{
+ matrix.getMin());
long start = System.currentTimeMillis();
AverageDistanceEngine clusterer = new AverageDistanceEngine(
- af.getViewport(), null, matrix);
+ af.getViewport(), null, matrix, false);
System.out.println("built a tree in "
+ (System.currentTimeMillis() - start) * 0.001 + " seconds.");
StringBuffer sb = new StringBuffer();
verifyPAEmatrix(seq, aa, 0, 0, 4);
// test clustering
- paematrix.setGroupSet(GroupSet.makeGroups(paematrix, 0.1f, false));
+ paematrix.setGroupSet(GroupSet.makeGroups(paematrix, false,0.1f, false));
// remap - test the MappableContactMatrix.liftOver method
SequenceI newseq = new Sequence("Seq", "ASDQEASDQEASDQE");
try
{
+ // fix for JAL-4153
// This delay is essential to prevent the assertion below from executing
// before swing thread finishes updating the combo-box
SwingUtilities.invokeAndWait(() -> {
try
{
+ // fix for JAL-4153
// This delay is to let cacheBox.updateCache() finish updating the cache
SwingUtilities.invokeAndWait(() -> {
try
{
paevals[i][j] = ((i - j < 2)
|| ((i > 1 && i < 5) && (j > 1 && i < 5))) ? 1 : 0f;
- paevals[j][i] = paevals[i][j];
+ paevals[j][i] = -paevals[i][j];
}
}
PAEContactMatrix dummyMat = new PAEContactMatrix(sq, paevals);
float[][] vals = ContactMatrix.fromFloatStringToContacts(content,
sq.getLength(), sq.getLength());
assertEquals(vals[3][4], paevals[3][4]);
- dummyMat.setGroupSet(GroupSet.makeGroups(dummyMat, 0.5f, false));
+ assertEquals(vals[4][3], paevals[4][3]);
+ dummyMat.setGroupSet(GroupSet.makeGroups(dummyMat, false,0.5f, false));
Assert.assertNotSame(dummyMat.getNewick(), "");
AlignmentAnnotation paeCm = sq.addContactList(dummyMat);
al.addAnnotation(paeCm);
--- /dev/null
+{
+ "name": "Jalview",
+ "description": "Jalview is a free program for multiple sequence alignment editing, visualisation and analysis. Use it to view and edit sequence alignments, analyse them with phylogenetic trees and principal components analysis (PCA) plots and explore molecular structures and annotation.",
+ "homepage": "https://www.jalview.org/",
+ "biotoolsID": "Jalview",
+ "biotoolsCURIE": "biotools:Jalview",
+ "version": [
+ "2.11.2.7"
+ ],
+ "relation": [
+ {
+ "biotoolsID": "jabaws",
+ "type": "uses"
+ },
+ {
+ "biotoolsID": "chimera",
+ "type": "uses"
+ },
+ {
+ "biotoolsID": "chimerax",
+ "type": "uses"
+ },
+ {
+ "biotoolsID": "pymol",
+ "type": "uses"
+ },
+ {
+ "biotoolsID": "bioconda",
+ "type": "includedIn"
+ },
+ {
+ "biotoolsID": "3d-beacons",
+ "type": "uses"
+ },
+ {
+ "biotoolsID": "uniprot",
+ "type": "uses"
+ },
+ {
+ "biotoolsID": "pfam",
+ "type": "uses"
+ },
+ {
+ "biotoolsID": "ensembl",
+ "type": "uses"
+ },
+ {
+ "biotoolsID": "pdb",
+ "type": "uses"
+ },
+ {
+ "biotoolsID": "rfam",
+ "type": "uses"
+ }
+ ],
+ "function": [
+ {
+ "operation": [
+ {
+ "uri": "http://edamontology.org/operation_0564",
+ "term": "Sequence visualisation"
+ },
+ {
+ "uri": "http://edamontology.org/operation_0324",
+ "term": "Phylogenetic tree analysis"
+ },
+ {
+ "uri": "http://edamontology.org/operation_3081",
+ "term": "Sequence alignment editing"
+ }
+ ],
+ "input": [
+ {
+ "data": {
+ "uri": "http://edamontology.org/data_0863",
+ "term": "Sequence alignment"
+ },
+ "format": [
+ {
+ "uri": "http://edamontology.org/format_1939",
+ "term": "GFF3-seq"
+ },
+ {
+ "uri": "http://edamontology.org/format_1982",
+ "term": "ClustalW format"
+ },
+ {
+ "uri": "http://edamontology.org/format_1961",
+ "term": "Stockholm format"
+ },
+ {
+ "uri": "http://edamontology.org/format_1984",
+ "term": "FASTA-aln"
+ },
+ {
+ "uri": "http://edamontology.org/format_1938",
+ "term": "GFF2-seq"
+ },
+ {
+ "uri": "http://edamontology.org/format_1929",
+ "term": "FASTA"
+ },
+ {
+ "uri": "http://edamontology.org/format_1948",
+ "term": "nbrf/pir"
+ },
+ {
+ "uri": "http://edamontology.org/format_3774",
+ "term": "BioJSON (Jalview)"
+ },
+ {
+ "uri": "http://edamontology.org/format_1997",
+ "term": "PHYLIP format"
+ },
+ {
+ "uri": "http://edamontology.org/format_3313",
+ "term": "BLC"
+ },
+ {
+ "uri": "http://edamontology.org/format_3311",
+ "term": "RNAML"
+ },
+ {
+ "uri": "http://edamontology.org/format_1947",
+ "term": "GCG MSF"
+ },
+ {
+ "uri": "http://edamontology.org/format_3015",
+ "term": "Pileup"
+ },
+ {
+ "uri": "http://edamontology.org/format_1477",
+ "term": "mmCIF"
+ },
+ {
+ "uri": "http://edamontology.org/format_3016",
+ "term": "VCF"
+ },
+ {
+ "uri": "http://edamontology.org/format_1915",
+ "term": "Format"
+ }
+ ]
+ },
+ {
+ "data": {
+ "uri": "http://edamontology.org/data_0886",
+ "term": "Structure alignment"
+ },
+ "format": [
+ {
+ "uri": "http://edamontology.org/format_1476",
+ "term": "PDB"
+ }
+ ]
+ }
+ ],
+ "output": [
+ {
+ "data": {
+ "uri": "http://edamontology.org/data_0863",
+ "term": "Sequence alignment"
+ },
+ "format": [
+ {
+ "uri": "http://edamontology.org/format_1948",
+ "term": "nbrf/pir"
+ },
+ {
+ "uri": "http://edamontology.org/format_3464",
+ "term": "JSON"
+ },
+ {
+ "uri": "http://edamontology.org/format_1961",
+ "term": "Stockholm format"
+ },
+ {
+ "uri": "http://edamontology.org/format_1929",
+ "term": "FASTA"
+ },
+ {
+ "uri": "http://edamontology.org/format_1997",
+ "term": "PHYLIP format"
+ },
+ {
+ "uri": "http://edamontology.org/format_3313",
+ "term": "BLC"
+ },
+ {
+ "uri": "http://edamontology.org/format_3774",
+ "term": "BioJSON (Jalview)"
+ },
+ {
+ "uri": "http://edamontology.org/format_1947",
+ "term": "GCG MSF"
+ },
+ {
+ "uri": "http://edamontology.org/format_3015",
+ "term": "Pileup"
+ },
+ {
+ "uri": "http://edamontology.org/format_1982",
+ "term": "ClustalW format"
+ }
+ ]
+ },
+ {
+ "data": {
+ "uri": "http://edamontology.org/data_2884",
+ "term": "Plot"
+ },
+ "format": [
+ {
+ "uri": "http://edamontology.org/format_3603",
+ "term": "PNG"
+ },
+ {
+ "uri": "http://edamontology.org/format_2331",
+ "term": "HTML"
+ },
+ {
+ "uri": "http://edamontology.org/format_3466",
+ "term": "EPS"
+ },
+ {
+ "uri": "http://edamontology.org/format_3604",
+ "term": "SVG"
+ },
+ {
+ "uri": "http://edamontology.org/format_1915",
+ "term": "Format"
+ }
+ ]
+ }
+ ],
+ "note": "Other Input formats:\nAMSA (.amsa);\nJnetFile (.concise, .jnet);\nPFAM (.pfam);\nSubstitution matrix (.matrix);\nJalview Project File (.jvp);\nJalview Feature File (.features, .jvfeatures);\nJalview Annotations File (.annotations, .jvannotations);\n\n...\nOther Output formats:\nPFAM (.pfam);\nBioJS (.biojs) (interactive HTML/Javascript);\nJalview Project File (.jvp);"
+ }
+ ],
+ "toolType": [
+ "Desktop application"
+ ],
+ "topic": [
+ {
+ "uri": "http://edamontology.org/topic_0080",
+ "term": "Sequence analysis"
+ },
+ {
+ "uri": "http://edamontology.org/topic_0092",
+ "term": "Data visualisation"
+ }
+ ],
+ "operatingSystem": [
+ "Linux",
+ "Windows",
+ "Mac"
+ ],
+ "license": "GPL-3.0",
+ "maturity": "Mature",
+ "cost": "Free of charge",
+ "accessibility": "Open access",
+ "elixirPlatform": [
+ "Tools"
+ ],
+ "elixirNode": [
+ "UK"
+ ],
+ "link": [
+ {
+ "url": "https://discourse.jalview.org/",
+ "type": [
+ "Discussion forum"
+ ]
+ },
+ {
+ "url": "https://issues.jalview.org/",
+ "type": [
+ "Issue tracker"
+ ]
+ },
+ {
+ "url": "https://www.jalview.org/development/jalview_develop/",
+ "type": [
+ "Other"
+ ],
+ "note": "Latest development version"
+ },
+ {
+ "url": "https://source.jalview.org/crucible/browse/jalview",
+ "type": [
+ "Repository"
+ ]
+ },
+ {
+ "url": "https://twitter.com/Jalview",
+ "type": [
+ "Social media"
+ ],
+ "note": "Twitter feed"
+ },
+ {
+ "url": "https://www.youtube.com/channel/UCIjpnvZB770yz7ftbrJ0tfw",
+ "type": [
+ "Social media"
+ ],
+ "note": "YouTube training videos"
+ }
+ ],
+ "download": [
+ {
+ "url": "https://www.jalview.org/download",
+ "type": "Downloads page"
+ },
+ {
+ "url": "https://www.jalview.org/download/source/",
+ "type": "Source code"
+ },
+ {
+ "url": "https://www.jalview.org/download/?os=all",
+ "type": "Binaries",
+ "note": "Binaries for all platforms"
+ },
+ {
+ "url": "https://www.jalview.org/favicon.svg",
+ "type": "Icon"
+ },
+ {
+ "url": "https://www.jalview.org/download/other/jar/",
+ "type": "Binaries",
+ "note": "Executable JAR file"
+ }
+ ],
+ "documentation": [
+ {
+ "url": "https://www.jalview.org/about/citation",
+ "type": [
+ "Citation instructions"
+ ]
+ },
+ {
+ "url": "https://www.jalview.org/training/",
+ "type": [
+ "Training material"
+ ],
+ "note": "Hands-on exercises, Training courses and Training videos"
+ },
+ {
+ "url": "https://www.jalview.org/help/faq",
+ "type": [
+ "FAQ"
+ ]
+ },
+ {
+ "url": "https://www.jalview.org/help/documentation/",
+ "type": [
+ "User manual"
+ ]
+ }
+ ],
+ "publication": [
+ {
+ "doi": "10.1093/bioinformatics/btp033",
+ "metadata": {
+ "title": "Jalview Version 2-A multiple sequence alignment editor and analysis workbench",
+ "abstract": "Summary: Jalview Version 2 is a system for interactive WYSIWYG editing, analysis and annotation of multiple sequence alignments. Core features include keyboard and mouse-based editing, multiple views and alignment overviews, and linked structure display with Jmol. Jalview 2 is available in two forms: a lightweight Java applet for use in web applications, and a powerful desktop application that employs web services for sequence alignment, secondary structure prediction and the retrieval of alignments, sequences, annotation and structures from public databases and any DAS 1.53 compliant sequence or annotation server. © 2009 The Author(s).",
+ "date": "2009-05-07T00:00:00Z",
+ "citationCount": 5999,
+ "authors": [
+ {
+ "name": "Waterhouse A.M."
+ },
+ {
+ "name": "Procter J.B."
+ },
+ {
+ "name": "Martin D.M.A."
+ },
+ {
+ "name": "Clamp M."
+ },
+ {
+ "name": "Barton G.J."
+ }
+ ],
+ "journal": "Bioinformatics"
+ }
+ }
+ ],
+ "credit": [
+ {
+ "name": "Jim Procter",
+ "url": "http://www.lifesci.dundee.ac.uk/people/jim-procter",
+ "orcidid": "https://orcid.org/0000-0002-7865-7382",
+ "typeEntity": "Person",
+ "typeRole": [
+ "Primary contact"
+ ]
+ },
+ {
+ "name": "Geoff Barton",
+ "url": "https://www.lifesci.dundee.ac.uk/people/geoff-barton",
+ "orcidid": "https://orcid.org/0000-0002-9014-5355"
+ }
+ ],
+ "owner": "ben_s",
+ "additionDate": "2019-02-13T17:01:40Z",
+ "lastUpdate": "2023-07-22T09:24:44.755337Z",
+ "editPermission": {
+ "type": "group",
+ "authors": [
+ "ben_s",
+ "jimprocter"
+ ]
+ },
+ "validated": 1,
+ "homepage_status": 0,
+ "elixir_badge": 0
+}
--- /dev/null
+This is the JSON representation of the latest Jalview release's record on bio.tools
+
+To update:
+1. go to https://bio.tools/Jalview
+2. log in and scroll down to the 'Update Record' button to open the edit interface.
+3. Make any chances to the entry - press Validate to ensure all is good
+4. Select the JSON tab and copy paste into
+
+``
+cat > utils/biotools/Jalview.json
+``
+
+Thanks to Herve Menager for the tutorial on storing bio.tools records with the tool's software repository at [CoFest 2023](https://www.open-bio.org/events/bosc-2023/obf-bosc-collaborationfest-2023)
\ No newline at end of file