From 323c280c255a8a8845beddc7f92fd36491469c6a Mon Sep 17 00:00:00 2001 From: MorellThomas Date: Wed, 22 May 2024 15:46:48 +0200 Subject: [PATCH] Save PaSiMap with Jalview Session --- src/jalview/gui/CalculationChooser.java | 2 +- src/jalview/gui/PaSiMapPanel.java | 4 +- src/jalview/gui/RotatableCanvas.java | 2 +- src/jalview/project/Jalview2XML.java | 228 +++++++++++++++++++++++++++++++ 4 files changed, 231 insertions(+), 5 deletions(-) diff --git a/src/jalview/gui/CalculationChooser.java b/src/jalview/gui/CalculationChooser.java index ee08d60..3b7ca81 100644 --- a/src/jalview/gui/CalculationChooser.java +++ b/src/jalview/gui/CalculationChooser.java @@ -769,7 +769,7 @@ public class CalculationChooser extends JPanel /* * construct the panel and kick off its calculation thread */ - pasimapPanel = new PaSiMapPanel(af.alignPanel, modelName, params); + pasimapPanel = new PaSiMapPanel(af.alignPanel, modelName); new Thread(pasimapPanel).start(); } diff --git a/src/jalview/gui/PaSiMapPanel.java b/src/jalview/gui/PaSiMapPanel.java index 74c7232..4a2d19d 100644 --- a/src/jalview/gui/PaSiMapPanel.java +++ b/src/jalview/gui/PaSiMapPanel.java @@ -98,10 +98,8 @@ public class PaSiMapPanel extends GPaSiMapPanel * * @param alignPanel * @param modelName - * @param params */ - public PaSiMapPanel(AlignmentPanel alignPanel, String modelName, - SimilarityParamsI params) + public PaSiMapPanel(AlignmentPanel alignPanel, String modelName) { super(8); // dim = 8 this.av = alignPanel.av; diff --git a/src/jalview/gui/RotatableCanvas.java b/src/jalview/gui/RotatableCanvas.java index 3a2089b..5261b23 100755 --- a/src/jalview/gui/RotatableCanvas.java +++ b/src/jalview/gui/RotatableCanvas.java @@ -516,8 +516,8 @@ public class RotatableCanvas extends JPanel { rectSelect(rectx1, recty1, rectx2, recty2); } - */ } + */ repaint(); } diff --git a/src/jalview/project/Jalview2XML.java b/src/jalview/project/Jalview2XML.java index 2f4052a..1b458ad 100644 --- a/src/jalview/project/Jalview2XML.java +++ b/src/jalview/project/Jalview2XML.java @@ -77,6 +77,7 @@ import javax.xml.stream.XMLStreamReader; import jalview.analysis.Conservation; import jalview.analysis.PCA; +import jalview.analysis.PaSiMap; import jalview.analysis.scoremodels.ScoreModels; import jalview.analysis.scoremodels.SimilarityParams; import jalview.api.FeatureColourI; @@ -122,6 +123,7 @@ import jalview.gui.JvOptionPane; import jalview.gui.OOMWarning; import jalview.gui.OverviewPanel; import jalview.gui.PCAPanel; +import jalview.gui.PaSiMapPanel; import jalview.gui.PaintRefresher; import jalview.gui.SplitFrame; import jalview.gui.StructureViewer; @@ -152,6 +154,7 @@ import jalview.util.jarInputStreamProvider; import jalview.util.matcher.Condition; import jalview.viewmodel.AlignmentViewport; import jalview.viewmodel.PCAModel; +import jalview.viewmodel.PaSiMapModel; import jalview.viewmodel.ViewportRanges; import jalview.viewmodel.seqfeatures.FeatureRendererModel; import jalview.viewmodel.seqfeatures.FeatureRendererSettings; @@ -1432,6 +1435,14 @@ public class Jalview2XML savePCA(panel, object); } } + if (frame instanceof PaSiMapPanel) + { + PaSiMapPanel panel = (PaSiMapPanel) frame; + if (panel.getAlignViewport().getAlignment() == jal) + { + savePaSiMap(panel, object); + } + } } } @@ -1980,6 +1991,101 @@ public class Jalview2XML } /** + * Writes PaSiMap viewer attributes and computed values to an XML model object and + * adds it to the JalviewModel. Any exceptions are reported by logging. + * uses the functions from PCA + */ + protected void savePaSiMap(PaSiMapPanel panel, JalviewModel object) + { + try + { + PcaViewer viewer = new PcaViewer(); + viewer.setHeight(panel.getHeight()); + viewer.setWidth(panel.getWidth()); + viewer.setXpos(panel.getX()); + viewer.setYpos(panel.getY()); + viewer.setTitle(panel.getTitle()); + PaSiMapModel pasimapModel = panel.getPasimapModel(); + viewer.setScoreModelName(pasimapModel.getScoreModelName()); + viewer.setXDim(panel.getSelectedDimensionIndex(X)); + viewer.setYDim(panel.getSelectedDimensionIndex(Y)); + viewer.setZDim(panel.getSelectedDimensionIndex(Z)); + viewer.setBgColour( + panel.getRotatableCanvas().getBackgroundColour().getRGB()); + viewer.setScaleFactor(panel.getRotatableCanvas().getScaleFactor()); + float[] spMin = panel.getRotatableCanvas().getSeqMin(); + SeqPointMin spmin = new SeqPointMin(); + spmin.setXPos(spMin[0]); + spmin.setYPos(spMin[1]); + spmin.setZPos(spMin[2]); + viewer.setSeqPointMin(spmin); + float[] spMax = panel.getRotatableCanvas().getSeqMax(); + SeqPointMax spmax = new SeqPointMax(); + spmax.setXPos(spMax[0]); + spmax.setYPos(spMax[1]); + spmax.setZPos(spMax[2]); + viewer.setSeqPointMax(spmax); + viewer.setShowLabels(panel.getRotatableCanvas().isShowLabels()); + viewer.setLinkToAllViews( + panel.getRotatableCanvas().isApplyToAllViews()); + /* + SimilarityParamsI sp = pasimapModel.getSimilarityParameters(); + viewer.setIncludeGaps(sp.includeGaps()); + viewer.setMatchGaps(sp.matchGaps()); + viewer.setIncludeGappedColumns(sp.includeGappedColumns()); + viewer.setDenominateByShortestLength(sp.denominateByShortestLength()); + */ + + /* + * sequence points on display + */ + for (jalview.datamodel.SequencePoint spt : pasimapModel + .getSequencePoints()) + { + SequencePoint point = new SequencePoint(); + point.setSequenceRef(seqHash(spt.getSequence())); + point.setXPos(spt.coord.x); + point.setYPos(spt.coord.y); + point.setZPos(spt.coord.z); + viewer.getSequencePoint().add(point); + } + + /* + * (end points of) axes on display + */ + for (Point p : panel.getRotatableCanvas().getAxisEndPoints()) + { + + Axis axis = new Axis(); + axis.setXPos(p.x); + axis.setYPos(p.y); + axis.setZPos(p.z); + viewer.getAxis().add(axis); + } + + /* + * raw PaSiMap data (note we are not restoring PaSiMap inputs here - + * alignment view, score model, similarity parameters) + */ + PcaDataType data = new PcaDataType(); + viewer.setPcaData(data); + PaSiMap pasimap = pasimapModel.getPasimapData(); + + DoubleMatrix pm = new DoubleMatrix(); + saveDoubleMatrix(pasimap.getPairwiseScores(), pm); + data.setPairwiseMatrix(pm); + + DoubleMatrix eigenMatrix = new DoubleMatrix(); + data.setEigenMatrix(eigenMatrix); + saveDoubleMatrix(pasimap.getEigenmatrix(), eigenMatrix); + + object.getPcaViewer().add(viewer); + } catch (Throwable t) + { + Console.error("Error saving PaSiMap: " + t.getMessage()); + } + } + /** * Stores values from a matrix into an XML element, including (if present) the * D or E vectors * @@ -4398,6 +4504,7 @@ public class Jalview2XML { loadTrees(jalviewModel, view, af, av, ap); loadPCAViewers(jalviewModel, ap); + loadPaSiMapViewers(jalviewModel, ap); loadPDBStructures(jprovider, jseqs, af, ap); loadRnaViewers(jprovider, jseqs, ap); loadOverview(view, jalviewModel.getVersion(), af); @@ -6595,6 +6702,127 @@ public class Jalview2XML } /** + * Loads any saved PaSiMAp viewers using the function from PCA + * + * @param jms + * @param ap + */ + protected void loadPaSiMapViewers(JalviewModel model, AlignmentPanel ap) + { + try + { + List pcaviewers = model.getPcaViewer(); + for (PcaViewer viewer : pcaviewers) + { + String modelName = viewer.getScoreModelName(); + /* + SimilarityParamsI params = new SimilarityParams( + viewer.isIncludeGappedColumns(), viewer.isMatchGaps(), + viewer.isIncludeGaps(), + viewer.isDenominateByShortestLength()); + */ + + /* + * create the panel (without computing the PaSiMAp) + */ + PaSiMapPanel panel = new PaSiMapPanel(ap, modelName); + + panel.setTitle(viewer.getTitle()); + panel.setBounds(new Rectangle(viewer.getXpos(), viewer.getYpos(), + viewer.getWidth(), viewer.getHeight())); + + boolean showLabels = viewer.isShowLabels(); + panel.setShowLabels(showLabels); + panel.getRotatableCanvas().setShowLabels(showLabels); + panel.getRotatableCanvas() + .setBgColour(new Color(viewer.getBgColour())); + panel.getRotatableCanvas() + .setApplyToAllViews(viewer.isLinkToAllViews()); + + /* + * load PaSiMap output data + */ + ScoreModelI scoreModel = ScoreModels.getInstance() + .getScoreModel(modelName, ap); + PaSiMap pasimap = new PaSiMap(null, scoreModel, null); + PcaDataType pasimapData = viewer.getPcaData(); + + MatrixI pairwise = loadDoubleMatrix(pasimapData.getPairwiseMatrix()); + pasimap.setPairwiseScores(pairwise); + + MatrixI result = loadDoubleMatrix(pasimapData.getEigenMatrix()); + pasimap.setEigenmatrix(result); + + panel.getPasimapModel().setPaSiMap(pasimap); + + /* + * we haven't saved the input data! (JAL-2647 to do) + */ + panel.setInputData(null); + + /* + * add the sequence points for the PCA display + */ + List seqPoints = new ArrayList<>(); + for (SequencePoint sp : viewer.getSequencePoint()) + { + String seqId = sp.getSequenceRef(); + SequenceI seq = seqRefIds.get(seqId); + if (seq == null) + { + throw new IllegalStateException( + "Unmatched seqref for PaSiMap: " + seqId); + } + Point pt = new Point(sp.getXPos(), sp.getYPos(), sp.getZPos()); + jalview.datamodel.SequencePoint seqPoint = new jalview.datamodel.SequencePoint( + seq, pt); + seqPoints.add(seqPoint); + } + panel.getRotatableCanvas().setPoints(seqPoints, seqPoints.size()); + + /* + * set min-max ranges and scale after setPoints (which recomputes them) + */ + panel.getRotatableCanvas().setScaleFactor(viewer.getScaleFactor()); + SeqPointMin spMin = viewer.getSeqPointMin(); + float[] min = new float[] { spMin.getXPos(), spMin.getYPos(), + spMin.getZPos() }; + SeqPointMax spMax = viewer.getSeqPointMax(); + float[] max = new float[] { spMax.getXPos(), spMax.getYPos(), + spMax.getZPos() }; + panel.getRotatableCanvas().setSeqMinMax(min, max); + + // todo: hold points list in PCAModel only + panel.getPasimapModel().setSequencePoints(seqPoints); + + panel.setSelectedDimensionIndex(viewer.getXDim(), X); + panel.setSelectedDimensionIndex(viewer.getYDim(), Y); + panel.setSelectedDimensionIndex(viewer.getZDim(), Z); + + // is this duplication needed? + panel.setTop(seqPoints.size() - 1); + panel.getPasimapModel().setTop(seqPoints.size() - 1); + + /* + * add the axes' end points for the display + */ + for (int i = 0; i < 3; i++) + { + Axis axis = viewer.getAxis().get(i); + panel.getRotatableCanvas().getAxisEndPoints()[i] = new Point( + axis.getXPos(), axis.getYPos(), axis.getZPos()); + } + + Desktop.addInternalFrame(panel, MessageManager.formatMessage( + "label.calc_title", "PaSiMap", modelName), 475, 450); + } + } catch (Exception ex) + { + Console.error("Error loading PaSiMap: " + ex.toString()); + } + } + + /** * Creates a new structure viewer window * * @param viewerType -- 1.7.10.2