import java.awt.Color;
import java.awt.Font;
+import java.awt.FontMetrics;
import java.awt.Rectangle;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.Collections;
import java.util.Enumeration;
import java.util.GregorianCalendar;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ContactMatrix;
+import jalview.datamodel.ContactMatrixI;
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.GeneLocus;
import jalview.datamodel.GraphLine;
import jalview.gui.Desktop;
import jalview.gui.JvOptionPane;
import jalview.gui.OOMWarning;
+import jalview.gui.OverviewPanel;
import jalview.gui.PCAPanel;
import jalview.gui.PaintRefresher;
import jalview.gui.SplitFrame;
import jalview.viewmodel.seqfeatures.FeatureRendererModel;
import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
+import jalview.ws.datamodel.alphafold.PAEContactMatrix;
import jalview.ws.jws2.Jws2Discoverer;
import jalview.ws.jws2.dm.AAConSettings;
import jalview.ws.jws2.jabaws2.Jws2Instance;
import jalview.xml.binding.jalview.JalviewModel.Viewport;
import jalview.xml.binding.jalview.JalviewModel.Viewport.CalcIdParam;
import jalview.xml.binding.jalview.JalviewModel.Viewport.HiddenColumns;
+import jalview.xml.binding.jalview.JalviewModel.Viewport.Overview;
import jalview.xml.binding.jalview.JalviewUserColours;
import jalview.xml.binding.jalview.JalviewUserColours.Colour;
import jalview.xml.binding.jalview.MapListType.MapListFrom;
import jalview.xml.binding.jalview.MapListType.MapListTo;
import jalview.xml.binding.jalview.Mapping;
+import jalview.xml.binding.jalview.MatrixType;
import jalview.xml.binding.jalview.NoValueColour;
import jalview.xml.binding.jalview.ObjectFactory;
import jalview.xml.binding.jalview.PcaDataType;
private static final String UTF_8 = "UTF-8";
/**
+ * used in decision if quit confirmation should be issued
+ */
+ private static boolean stateSavedUpToDate = false;
+
+ /**
* prefix for recovering datasets for alignments with multiple views where
* non-existent dataset IDs were written for some views
*/
{
AlignFrame[] frames = Desktop.getAlignFrames();
+ setStateSavedUpToDate(true);
+
+ if (Cache.getDefault("DEBUG_DELAY_SAVE", false))
+ {
+ int n = debugDelaySave;
+ int i = 0;
+ while (i < n)
+ {
+ Console.debug("***** debugging save sleep " + i + "/" + n);
+ try
+ {
+ Thread.sleep(1000);
+ } catch (InterruptedException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ i++;
+ }
+ }
+
if (frames == null)
{
return;
FileOutputStream fos = new FileOutputStream(
doBackup ? backupfiles.getTempFilePath() : jarFile);
+ if (Cache.getDefault("DEBUG_DELAY_SAVE", false))
+ {
+ int n = debugDelaySave;
+ int i = 0;
+ while (i < n)
+ {
+ Console.debug("***** debugging save sleep " + i + "/" + n);
+ try
+ {
+ Thread.sleep(1000);
+ } catch (InterruptedException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ i++;
+ }
+ }
+
JarOutputStream jout = new JarOutputStream(fos);
List<AlignFrame> frames = new ArrayList<>();
{
System.err.println("error writing date: " + e.toString());
}
- object.setVersion(
- Cache.getDefault("VERSION", "Development Build"));
+ object.setVersion(Cache.getDefault("VERSION", "Development Build"));
/**
* rjal is full height alignment, jal is actual alignment with full metadata
tree.setLinkToAllViews(
tp.getTreeCanvas().isApplyToAllViews());
+ // columnWiseTree
+ if (tp.isColumnWise())
+ {
+ tree.setColumnWise(true);
+ String annId = tp.getAssocAnnotation().annotationId;
+ tree.setColumnReference(annId);
+ }
// jms.addTree(tree);
object.getTree().add(tree);
}
view.setStartRes(vpRanges.getStartRes());
view.setStartSeq(vpRanges.getStartSeq());
+ OverviewPanel ov = ap.getOverviewPanel();
+ if (ov != null)
+ {
+ Overview overview = new Overview();
+ overview.setTitle(ov.getTitle());
+ Rectangle bounds = ov.getFrameBounds();
+ overview.setXpos(bounds.x);
+ overview.setYpos(bounds.y);
+ overview.setWidth(bounds.width);
+ overview.setHeight(bounds.height);
+ overview.setShowHidden(ov.isShowHiddenRegions());
+ overview.setGapColour(ov.getCanvas().getGapColour().getRGB());
+ overview.setResidueColour(
+ ov.getCanvas().getResidueColour().getRGB());
+ overview.setHiddenColour(ov.getCanvas().getHiddenColour().getRGB());
+ view.setOverview(overview);
+ }
if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
{
view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
view.setConservationSelected(av.getConservationSelected());
view.setPidSelected(av.getAbovePIDThreshold());
+ view.setCharHeight(av.getCharHeight());
+ view.setCharWidth(av.getCharWidth());
final Font font = av.getFont();
view.setFontName(font.getName());
view.setFontSize(font.getSize());
.getHiddenColumns();
if (hidden == null)
{
- Console.warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
+ Console.warn(
+ "REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
}
else
{
line.setColour(annotation.getThreshold().colour.getRGB());
an.setThresholdLine(line);
}
+ if (annotation.graph==AlignmentAnnotation.CONTACT_MAP)
+ {
+ if (annotation.sequenceRef.getContactMaps()!=null)
+ {
+ ContactMatrixI cm = annotation.sequenceRef.getContactMatrixFor(annotation);
+ if (cm!=null)
+ {
+ MatrixType xmlmat = new MatrixType();
+ xmlmat.setType(cm.getType());
+ xmlmat.setRows(BigInteger.valueOf(cm.getWidth()));
+ xmlmat.setCols(BigInteger.valueOf(cm.getHeight()));
+ // consider using an opaque to/from -> allow instance to control its representation ?
+ xmlmat.setElements(ContactMatrix.contactToFloatString(cm));
+ if (cm.hasGroups())
+ {
+ for (BitSet gp: cm.getGroups())
+ {
+ BigInteger val = new BigInteger(gp.toByteArray());
+ xmlmat.getGroups().add(val.toString());
+ }
+ }
+ if (cm.hasTree())
+ {
+ // provenance object for tree ?
+ xmlmat.getNewick().add(cm.getNewick());
+ xmlmat.setTreeMethod(cm.getTreeMethod());
+ }
+ if (cm.hasCutHeight())
+ {
+ xmlmat.setCutHeight(cm.getCutHeight());
+ }
+
+ // set/get properties
+ an.getContactmatrix().add(xmlmat);
+ }
+ }
+ }
}
else
{
{
for (String pr : annotation.getProperties())
{
- jalview.xml.binding.jalview.Annotation.Property prop = new jalview.xml.binding.jalview.Annotation.Property();
+ jalview.xml.binding.jalview.Property prop = new jalview.xml.binding.jalview.Property();
prop.setName(pr);
prop.setValue(annotation.getProperty(pr));
- // an.addProperty(prop);
an.getProperty().add(prop);
}
}
}
else
{
- Console.warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
+ Console.warn(
+ "Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
return false;
}
}
return id.toString();
}
// give up and warn that something has gone wrong
- Console.warn("Cannot find ID for object in external mapping : " + jvobj);
+ Console.warn(
+ "Cannot find ID for object in external mapping : " + jvobj);
}
return altCode;
}
}
else
{
- Console.warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
+ Console.warn(
+ "Couldn't find entry in Jalview Jar for " + jarEntryName);
}
} catch (Exception ex)
{
jaa.setCalcId(annotation.getCalcId());
if (annotation.getProperty().size() > 0)
{
- for (Annotation.Property prop : annotation.getProperty())
+ for (jalview.xml.binding.jalview.Property prop : annotation.getProperty())
{
jaa.setProperty(prop.getName(), prop.getValue());
}
}
+ if (jaa.graph == AlignmentAnnotation.CONTACT_MAP)
+ {
+ if (annotation.getContactmatrix() != null
+ && annotation.getContactmatrix().size() > 0)
+ {
+ for (MatrixType xmlmat : annotation.getContactmatrix())
+ {
+ if (PAEContactMatrix.PAEMATRIX.equals(xmlmat.getType()))
+ {
+ if (!xmlmat.getRows().equals(xmlmat.getCols()))
+ {
+ Console.error("Can't handle non square PAE Matrices");
+ }
+ else
+ {
+ float[][] elements = ContactMatrix
+ .fromFloatStringToContacts(xmlmat.getElements(),
+ xmlmat.getCols().intValue(),
+ xmlmat.getRows().intValue());
+
+ PAEContactMatrix newpae = new PAEContactMatrix(
+ jaa.sequenceRef, elements);
+ List<BitSet> newgroups=new ArrayList<BitSet>();
+ if (xmlmat.getGroups().size()>0)
+ {
+ for (String sgroup:xmlmat.getGroups())
+ {
+ try {
+ BigInteger group = new BigInteger(sgroup);
+ newgroups.add(BitSet.valueOf(group.toByteArray()));
+ } catch (NumberFormatException nfe)
+ {
+ Console.error("Problem parsing groups for a contact matrix (\""+sgroup+"\"",nfe);
+ }
+ }
+ }
+ String nwk=xmlmat.getNewick().size()>0 ? xmlmat.getNewick().get(0):null;
+ if (xmlmat.getNewick().size()>1)
+ {
+ Console.log.info(
+ "Ignoring additional clusterings for contact matrix");
+ }
+
+ String treeMethod = xmlmat.getTreeMethod();
+ double thresh = xmlmat.getCutHeight()!=null ? xmlmat.getCutHeight() : 0;
+ newpae.restoreGroups(newgroups, treeMethod, nwk, thresh);
+ jaa.sequenceRef.addContactListFor(jaa, newpae);
+ }
+ }
+ else
+ {
+ Console.error("Ignoring CONTACT_MAP annotation with type "
+ + xmlmat.getType());
+ }
+ }
+ }
+ }
+
if (jaa.autoCalculated)
{
autoAlan.add(new JvAnnotRow(i, jaa));
}
/*
- * Load any trees, PDB structures and viewers
+ * Load any trees, PDB structures and viewers, Overview
*
* Not done if flag is false (when this method is used for New View)
*/
loadPCAViewers(jalviewModel, ap);
loadPDBStructures(jprovider, jseqs, af, ap);
loadRnaViewers(jprovider, jseqs, ap);
+ loadOverview(view, jalviewModel.getVersion(), af);
}
// and finally return.
return af;
}
/**
+ * Load Overview window, restoring colours, 'show hidden regions' flag, title
+ * and geometry as saved
+ *
+ * @param view
+ * @param af
+ */
+ protected void loadOverview(Viewport view, String version, AlignFrame af)
+ {
+ if (!isVersionStringLaterThan("2.11.3",
+ version) && view.getOverview()==null)
+ {
+ return;
+ }
+ /*
+ * first close any Overview that was opened automatically
+ * (if so configured in Preferences) so that the view is
+ * restored in the same state as saved
+ */
+ af.alignPanel.closeOverviewPanel();
+
+ Overview overview = view.getOverview();
+ if (overview != null)
+ {
+ OverviewPanel overviewPanel = af
+ .openOverviewPanel(overview.isShowHidden());
+ overviewPanel.setTitle(overview.getTitle());
+ overviewPanel.setFrameBounds(overview.getXpos(), overview.getYpos(),
+ overview.getWidth(), overview.getHeight());
+ Color gap = new Color(overview.getGapColour());
+ Color residue = new Color(overview.getResidueColour());
+ Color hidden = new Color(overview.getHiddenColour());
+ overviewPanel.getCanvas().setColours(gap, residue, hidden);
+ }
+ }
+
+ /**
* Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
* panel is restored from separate jar entries, two (gapped and trimmed) per
* sequence and secondary structure.
TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
if (tp == null)
{
- tp = af.showNewickTree(new NewickFile(tree.getNewick()),
- tree.getTitle(), safeInt(tree.getWidth()),
- safeInt(tree.getHeight()), safeInt(tree.getXpos()),
- safeInt(tree.getYpos()));
+ if (tree.isColumnWise())
+ {
+ AlignmentAnnotation aa = (AlignmentAnnotation) annotationIds.get(tree
+ .getColumnReference());
+ if (aa == null)
+ {
+ Console.warn(
+ "Null alignment annotation when restoring columnwise tree");
+ }
+ tp = af.showColumnWiseTree(new NewickFile(tree.getNewick()), aa,
+ tree.getTitle(), safeInt(tree.getWidth()),
+ safeInt(tree.getHeight()), safeInt(tree.getXpos()),
+ safeInt(tree.getYpos()));
+
+ }
+ else
+ {
+ tp = af.showNewickTree(new NewickFile(tree.getNewick()),
+ tree.getTitle(), safeInt(tree.getWidth()),
+ safeInt(tree.getHeight()), safeInt(tree.getXpos()),
+ safeInt(tree.getYpos()));
+ }
if (tree.getId() != null)
{
// perhaps bind the tree id to something ?
tp.getTreeCanvas().setApplyToAllViews(tree.isLinkToAllViews());
if (tp == null)
{
- Console.warn("There was a problem recovering stored Newick tree: \n"
- + tree.getNewick());
+ Console.warn(
+ "There was a problem recovering stored Newick tree: \n"
+ + tree.getNewick());
continue;
}
* - minimum version we are comparing against
* @param version
* - version of data being processsed
- * @return
+ * @return true if version is equal to or later than supported
*/
public static boolean isVersionStringLaterThan(String supported,
String version)
viewport.setRightAlignIds(safeBoolean(view.isRightAlignIds()));
viewport.setFont(new Font(view.getFontName(),
safeInt(view.getFontStyle()), safeInt(view.getFontSize())),
- true);
+ (view.getCharWidth()!=null) ? false : true);
+ if (view.getCharWidth()!=null)
+ {
+ viewport.setCharWidth(view.getCharWidth());
+ viewport.setCharHeight(view.getCharHeight());
+ }
ViewStyleI vs = viewport.getViewStyle();
vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
viewport.setViewStyle(vs);
{
splitFrameCandidates.put(view, af);
}
+
return af;
}
+ annotationId);
return null;
}
- if (matchedAnnotation.getThreshold() == null)
+ // belt-and-braces create a threshold line if the
+ // colourscheme needs one but the matchedAnnotation doesn't have one
+ if (safeInt(viewAnnColour.getAboveThreshold()) != 0
+ && matchedAnnotation.getThreshold() == null)
{
matchedAnnotation.setThreshold(
new GraphLine(safeFloat(viewAnnColour.getThreshold()),
{
if (ds != null && ds != seqSetDS)
{
- Console.warn("JAL-3171 regression: Overwriting a dataset reference for an alignment"
- + " - CDS/Protein crossreference data may be lost");
+ Console.warn(
+ "JAL-3171 regression: Overwriting a dataset reference for an alignment"
+ + " - CDS/Protein crossreference data may be lost");
if (xtant_ds != null)
{
// This can only happen if the unique sequence set ID was bound to a
// dataset that did not contain any of the sequences in the view
// currently being restored.
- Console.warn("JAL-3171 SERIOUS! TOTAL CONFUSION - please consider contacting the Jalview Development team so they can investigate why your project caused this message to be displayed.");
+ Console.warn(
+ "JAL-3171 SERIOUS! TOTAL CONFUSION - please consider contacting the Jalview Development team so they can investigate why your project caused this message to be displayed.");
}
}
ds = seqSetDS;
{
if (dataset.getDataset() != null)
{
- Console.warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
+ Console.warn(
+ "Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
}
String datasetId = makeHashCode(dataset, null);
if (datasetId == null)
}
else
{
- Console.warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
+ Console.warn(
+ "Couldn't find entry in Jalview Jar for " + jarEntryName);
}
} catch (Exception ex)
{
return colour;
}
+
+ public static void setStateSavedUpToDate(boolean s)
+ {
+ Console.debug("Setting overall stateSavedUpToDate to " + s);
+ stateSavedUpToDate = s;
+ }
+
+ public static boolean stateSavedUpToDate()
+ {
+ Console.debug("Returning overall stateSavedUpToDate value: "
+ + stateSavedUpToDate);
+ return stateSavedUpToDate;
+ }
+
+ public static boolean allSavedUpToDate()
+ {
+ if (stateSavedUpToDate()) // nothing happened since last project save
+ return true;
+
+ AlignFrame[] frames = Desktop.getAlignFrames();
+ if (frames != null)
+ {
+ for (int i = 0; i < frames.length; i++)
+ {
+ if (frames[i] == null)
+ continue;
+ if (!frames[i].getViewport().savedUpToDate())
+ return false; // at least one alignment is not individually saved
+ }
+ }
+ return true;
+ }
+
+ // used for debugging and tests
+ private static int debugDelaySave = 20;
+
+ public static void setDebugDelaySave(int n)
+ {
+ debugDelaySave = n;
+ }
}