From 31f1b88951cc5ff3aea7ae0bc1a9d8fbdd264ea3 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Mon, 26 Jan 2015 16:42:56 +0000 Subject: [PATCH] JAL-1588 restoring saved Chimera session(s) --- .../edu/ucsf/rbvi/strucviz2/ChimeraManager.java | 50 ++--- src/jalview/datamodel/PDBEntry.java | 24 ++- src/jalview/datamodel/ViewerData.java | 189 ++++++++++++++++++ .../ext/rbvi/chimera/JalviewChimeraBinding.java | 183 ++++++++--------- src/jalview/gui/AppJmol.java | 6 +- src/jalview/gui/ChimeraViewFrame.java | 84 +++++--- src/jalview/gui/Jalview2XML.java | 208 +++++++++----------- src/jalview/gui/StructureViewer.java | 12 +- 8 files changed, 459 insertions(+), 297 deletions(-) create mode 100644 src/jalview/datamodel/ViewerData.java diff --git a/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java b/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java index b45404e..2c40e1c 100644 --- a/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java +++ b/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java @@ -29,12 +29,6 @@ public class ChimeraManager { private static final boolean debug = false; - /* - * true: use REST API (recommended), false: use stdout/stdin (deprecated) - */ - // TODO remove once definitely happy with using REST - private static final boolean USE_REST = true; - private int chimeraRestPort; private Process chimera; @@ -224,10 +218,14 @@ public class ChimeraManager modelNumbers[0], modelNumbers[1]); currentModelsMap.put(modelNumber, newModel); models.add(newModel); + + // // patch for Jalview - set model name in Chimera + // sendChimeraCommand("setattr M name " + modelName + " #" + modelNumbers[0], false); // end patch for Jalview + modelNumbers = null; } } @@ -370,15 +368,7 @@ public class ChimeraManager { chimera = null; currentModelsMap.clear(); - if (USE_REST) - { this.chimeraRestPort = 0; - } - else - { - chimeraListenerThread.requestStop(); - chimeraListenerThread = null; - } structureManager.clearOnChimeraExit(); } @@ -549,13 +539,11 @@ public class ChimeraManager List args = new ArrayList(); args.add(chimeraPath); args.add("--start"); - args.add(USE_REST ? "RESTServer" : "ReadStdin"); + args.add("RESTServer"); ProcessBuilder pb = new ProcessBuilder(args); chimera = pb.start(); error = ""; workingPath = chimeraPath; - logger.info("Starting " + chimeraPath + " with " - + (USE_REST ? "REST API" : "stdin/stdout")); break; } catch (Exception e) { @@ -566,18 +554,9 @@ public class ChimeraManager // If no error, then Chimera was launched successfully if (error.length() == 0) { - if (USE_REST) - { - this.chimeraRestPort = getPortNumber(); - System.out.println("Chimera REST API on port " + chimeraRestPort); - } - else - { - // Initialize the listener threads - chimeraListenerThread = new ListenerThreads(chimera, - structureManager); - chimeraListenerThread.start(); - } + this.chimeraRestPort = getPortNumber(); + System.out.println("Chimera REST API started on port " + + chimeraRestPort); // structureManager.initChimTable(); structureManager.setChimeraPathProperty(workingPath); // TODO: [Optional] Check Chimera version and show a warning if below 1.8 @@ -766,22 +745,17 @@ public class ChimeraManager } catch (InterruptedException q) { } - ; } busy = true; long startTime = System.currentTimeMillis(); try { - if (USE_REST) - { - return sendRestCommand(command); - } - else - { - return sendStdinCommand(command, reply); - } + return sendRestCommand(command); } finally { + /* + * Make sure busy flag is reset come what may! + */ busy = false; if (debug) { diff --git a/src/jalview/datamodel/PDBEntry.java b/src/jalview/datamodel/PDBEntry.java index ee2b549..1cf9cd7 100755 --- a/src/jalview/datamodel/PDBEntry.java +++ b/src/jalview/datamodel/PDBEntry.java @@ -20,7 +20,7 @@ */ package jalview.datamodel; -import java.util.*; +import java.util.Hashtable; public class PDBEntry { @@ -37,6 +37,7 @@ public class PDBEntry * * @see java.lang.Object#equals(java.lang.Object) */ + @Override public boolean equals(Object obj) { if (obj == null || !(obj instanceof PDBEntry)) @@ -44,7 +45,9 @@ public class PDBEntry return false; } if (obj == this) + { return true; + } PDBEntry o = (PDBEntry) obj; return (file == o.file || (file != null && o.file != null && o.file .equals(file))) @@ -57,10 +60,29 @@ public class PDBEntry .equals(o.properties))); } + /** + * Default constructor + */ public PDBEntry() { } + /** + * Constructor given file path and PDB id. + * + * @param filePath + */ + public PDBEntry(String filePath, String pdbId) + { + this.file = filePath; + this.id = pdbId; + } + + /** + * Copy constructor. + * + * @param entry + */ public PDBEntry(PDBEntry entry) { file = entry.file; diff --git a/src/jalview/datamodel/ViewerData.java b/src/jalview/datamodel/ViewerData.java new file mode 100644 index 0000000..0b6b8d1 --- /dev/null +++ b/src/jalview/datamodel/ViewerData.java @@ -0,0 +1,189 @@ +package jalview.datamodel; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * A data bean to hold stored data about a structure viewer. + */ +public class ViewerData +{ + private int x; + + private int y; + + private int width; + + private int height; + + private boolean alignWithPanel; + + private boolean colourWithAlignPanel; + + private boolean colourByViewer; + + private String stateData = ""; + + private Map fileData = new HashMap(); + + public class StructureData + { + private String filePath; + + private String pdbId; + + private List seqList; + + // TODO and possibly a list of chains? + + /** + * Constructor given structure file path and id. + * + * @param pdbFile + * @param id + */ + public StructureData(String pdbFile, String id) + { + this.filePath = pdbFile; + this.pdbId = id; + this.seqList = new ArrayList(); + } + + public String getFilePath() + { + return filePath; + } + + protected void setFilePath(String filePath) + { + this.filePath = filePath; + } + + public String getPdbId() + { + return pdbId; + } + + protected void setPdbId(String pdbId) + { + this.pdbId = pdbId; + } + + public List getSeqList() + { + return seqList; + } + + protected void setSeqList(List seqList) + { + this.seqList = seqList; + } + } + + public ViewerData(int x, int y, int width, int height, + boolean alignWithPanel, boolean colourWithAlignPanel, + boolean colourByViewer) + { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.alignWithPanel = alignWithPanel; + this.colourWithAlignPanel = colourWithAlignPanel; + this.colourByViewer = colourByViewer; + } + + public int getX() + { + return x; + } + + protected void setX(int x) + { + this.x = x; + } + + public int getY() + { + return y; + } + + protected void setY(int y) + { + this.y = y; + } + + public int getWidth() + { + return width; + } + + protected void setWidth(int width) + { + this.width = width; + } + + public int getHeight() + { + return height; + } + + public void setHeight(int height) + { + this.height = height; + } + + public boolean isAlignWithPanel() + { + return alignWithPanel; + } + + public void setAlignWithPanel(boolean alignWithPanel) + { + this.alignWithPanel = alignWithPanel; + } + + public boolean isColourWithAlignPanel() + { + return colourWithAlignPanel; + } + + public void setColourWithAlignPanel(boolean colourWithAlignPanel) + { + this.colourWithAlignPanel = colourWithAlignPanel; + } + + public boolean isColourByViewer() + { + return colourByViewer; + } + + public void setColourByViewer(boolean colourByViewer) + { + this.colourByViewer = colourByViewer; + } + + public String getStateData() + { + return stateData; + } + + public void setStateData(String stateData) + { + this.stateData = stateData; + } + + public Map getFileData() + { + return fileData; + } + + protected void setFileData(Map fileData) + { + this.fileData = fileData; + } + +} diff --git a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java index 6e6f5ee..b345c5e 100644 --- a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java +++ b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java @@ -28,7 +28,6 @@ import jalview.datamodel.AlignmentI; import jalview.datamodel.ColumnSelection; import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceI; -import jalview.io.AppletFormatAdapter; import jalview.schemes.ColourSchemeI; import jalview.schemes.ResidueProperties; import jalview.structure.StructureMapping; @@ -39,7 +38,6 @@ import jalview.util.Comparison; import jalview.util.MessageManager; import java.awt.Color; -import java.io.File; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; @@ -65,123 +63,106 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel private ChimeraManager viewer; - /** + /* * set if chimera state is being restored from some source - instructs binding * not to apply default display style when structure set is updated for first * time. */ private boolean loadingFromArchive = false; - /** - * second flag to indicate if the Chimera viewer should ignore sequence - * colouring events from the structure manager because the GUI is still - * setting up + /* + * flag to indicate if the Chimera viewer should ignore sequence colouring + * events from the structure manager because the GUI is still setting up */ private boolean loadingFinished = true; - /** + /* * state flag used to check if the Chimera viewer's paint method can be called */ private boolean finishedInit = false; - public boolean isFinishedInit() - { - return finishedInit; - } - - public void setFinishedInit(boolean finishedInit) - { - this.finishedInit = finishedInit; - } - - boolean allChainsSelected = false; - - /** - * when true, try to search the associated datamodel for sequences that are - * associated with any unknown structures in the Chimera view. - */ - private boolean associateNewStructs = false; + private List atomsPicked = new ArrayList(); - List atomsPicked = new ArrayList(); - - public List chainNames; + private List chainNames; private Map chainFile; - StringBuffer eval = new StringBuffer(); + private StringBuffer eval = new StringBuffer(); public String fileLoadingError; - private Map> chimmaps = new LinkedHashMap>(); - - private List mdlToFile = new ArrayList(); + /* + * Map of ChimeraModel objects keyed by PDB full local file name + */ + private Map> chimeraMaps = new LinkedHashMap>(); - /** + /* * the default or current model displayed if the model cannot be identified * from the selection message */ - int frameNo = 0; + private int frameNo = 0; - String lastCommand; + private String lastCommand; - String lastMessage; + private String lastMessage; - boolean loadedInline; + private boolean loadedInline; + /** + * Open a PDB structure file in Chimera and set up mappings from Jalview. + * + * We check if the PDB model id is already loaded in Chimera, if so don't + * reopen it. This is the case if Chimera has opened a saved session file. + * + * @param pe + * @return + */ public boolean openFile(PDBEntry pe) { String file = pe.getFile(); try { + List modelsToMap = new ArrayList(); List oldList = viewer.getModelList(); - viewer.openModel(file, pe.getId(), ModelType.PDB_MODEL); - List newList = viewer.getModelList(); - if (oldList.size() < newList.size()) + boolean alreadyOpen = false; + + /* + * If Chimera already has this model, don't reopen it, but do remap it. + */ + for (ChimeraModel open : oldList) { - while (oldList.size() > 0) + if (open.getModelName().equals(pe.getId())) { - oldList.remove(0); - newList.remove(0); - } - chimmaps.put(file, newList); - for (ChimeraModel cm : newList) - { - while (mdlToFile.size() < 1 + cm.getModelNumber()) - { - mdlToFile.add(new String("")); - } - mdlToFile.set(cm.getModelNumber(), file); + alreadyOpen = true; + modelsToMap.add(open); } + } - File fl = new File(file); - String protocol = AppletFormatAdapter.URL; - try - { - if (fl.exists()) - { - protocol = AppletFormatAdapter.FILE; - } - } catch (Exception e) - { - } catch (Error e) - { - } - // Explicitly map to the filename used by Chimera ; - // pdbentry[pe].getFile(), protocol); + /* + * If Chimera doesn't yet have this model, ask it to open it, and retrieve + * the model names added by Chimera. + */ + if (!alreadyOpen) + { + viewer.openModel(file, pe.getId(), ModelType.PDB_MODEL); + modelsToMap = viewer.getModelList(); + modelsToMap.removeAll(oldList); + } + + chimeraMaps.put(file, modelsToMap); - if (getSsm() != null) + if (getSsm() != null) + { + getSsm().addStructureViewerListener(this); + // ssm.addSelectionListener(this); + FeatureRenderer fr = getFeatureRenderer(null); + if (fr != null) { - getSsm().addStructureViewerListener(this); - // ssm.addSelectionListener(this); - FeatureRenderer fr = getFeatureRenderer(null); - if (fr != null) - { - fr.featuresAdded(); - } - refreshGUI(); + fr.featuresAdded(); } - return true; + refreshGUI(); } + return true; } catch (Exception q) { log("Exception when trying to open model " + file + "\n" @@ -642,7 +623,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel { if (!viewer.isChimeraLaunched()) { - viewer.launchChimera(csm.getChimeraPaths()); + viewer.launchChimera(StructureManager.getChimeraPaths()); } if (!viewer.isChimeraLaunched()) { @@ -662,7 +643,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel } /** - * Send a command to Chimera, and optionally log any responses. + * Send a command to Chimera, launching it first if necessary, and optionally + * log any responses. * * @param command * @param logResponse @@ -673,28 +655,12 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel checkLaunched(); if (lastCommand == null || !lastCommand.equals(command)) { -// Thread t = new Thread(new Runnable() -// { -// @Override -// public void run() -// { // trim command or it may never find a match in the replyLog!! lastReply = viewer.sendChimeraCommand(command.trim(), logResponse); if (debug && logResponse) - { - log("Response from command ('" + command + "') was:\n" - + lastReply); - } -// } -// }); - // TODO - use j7/8 thread management -// try -// { -// t.join(); -// } catch (InterruptedException foo) -// { -// } -// ; + { + log("Response from command ('" + command + "') was:\n" + lastReply); + } } viewerCommandHistory(true); lastCommand = command; @@ -853,8 +819,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel // // System.arraycopy(mset, 0, modelFileNames, 0, j); // } - return chimmaps.keySet().toArray( - modelFileNames = new String[chimmaps.size()]); + return chimeraMaps.keySet().toArray( + modelFileNames = new String[chimeraMaps.size()]); } /** @@ -881,7 +847,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel public void highlightAtom(int atomIndex, int pdbResNum, String chain, String pdbfile) { - List cms = chimmaps.get(pdbfile); + List cms = chimeraMaps.get(pdbfile); if (cms != null) { int mdlNum = cms.get(0).getModelNumber(); @@ -1306,4 +1272,19 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel return true; } + public boolean isFinishedInit() + { + return finishedInit; + } + + public void setFinishedInit(boolean finishedInit) + { + this.finishedInit = finishedInit; + } + + public List getChainNames() + { + return chainNames; + } + } diff --git a/src/jalview/gui/AppJmol.java b/src/jalview/gui/AppJmol.java index bd4a393..a4fe27c 100644 --- a/src/jalview/gui/AppJmol.java +++ b/src/jalview/gui/AppJmol.java @@ -147,9 +147,7 @@ public class AppJmol extends StructureViewerBase PDBEntry[] pdbentrys = new PDBEntry[files.length]; for (int i = 0; i < pdbentrys.length; i++) { - PDBEntry pdbentry = new PDBEntry(); - pdbentry.setFile(files[i]); - pdbentry.setId(ids[i]); + PDBEntry pdbentry = new PDBEntry(files[i], ids[i]); pdbentrys[i] = pdbentry; } // / TODO: check if protocol is needed to be set, and if chains are @@ -169,7 +167,7 @@ public class AppJmol extends StructureViewerBase seqColour.setSelected(false); viewerColour.setSelected(true); } - if (usetoColour) + else if (usetoColour) { useAlignmentPanelForColourbyseq(ap); jmb.setColourBySequence(true); diff --git a/src/jalview/gui/ChimeraViewFrame.java b/src/jalview/gui/ChimeraViewFrame.java index 4e313b5..8ebd231 100644 --- a/src/jalview/gui/ChimeraViewFrame.java +++ b/src/jalview/gui/ChimeraViewFrame.java @@ -27,7 +27,6 @@ import jalview.datamodel.ColumnSelection; import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceI; import jalview.ext.rbvi.chimera.JalviewChimeraBinding; -import jalview.gui.Jalview2XML.ViewerData; import jalview.io.AppletFormatAdapter; import jalview.io.JalviewFileChooser; import jalview.io.JalviewFileView; @@ -99,9 +98,11 @@ public class ChimeraViewFrame extends StructureViewerBase private Thread worker = null; /* - * Path to Chimera session file - set in saveSession() + * Path to Chimera session file. This is set when an open Jalview/Chimera + * session is saved, or on restore from a Jalview project (if it holds the + * filename of any saved Chimera sessions). */ - private String chimeraSessionFile = ""; + private String chimeraSessionFile = null; /** * Initialise menu options. @@ -311,12 +312,11 @@ public class ChimeraViewFrame extends StructureViewerBase jmb.setColourBySequence(true); setSize(400, 400); // probably should be a configurable/dynamic default here initMenus(); - worker = null; - { - addingStructures = false; - worker = new Thread(this); - worker.start(); - } + + addingStructures = false; + worker = new Thread(this); + worker.start(); + this.addInternalFrameListener(new InternalFrameAdapter() { public void internalFrameClosing(InternalFrameEvent internalFrameEvent) @@ -343,20 +343,37 @@ public class ChimeraViewFrame extends StructureViewerBase } /** - * Create a new viewer from saved session state data. + * Create a new viewer from saved session state data including Chimera session + * file. + * + * @param chimeraSession * - * @param viewerData - * @param af + * @param alignPanel + * @param pdbArray + * @param seqsArray + * @param colourByChimera + * @param colourBySequence */ - public ChimeraViewFrame(ViewerData viewerData, AlignFrame af) + public ChimeraViewFrame(String chimeraSession, AlignmentPanel alignPanel, + PDBEntry[] pdbArray, + SequenceI[][] seqsArray, boolean colourByChimera, + boolean colourBySequence) { super(); - String chimeraSessionFile = viewerData.stateData; - openNewChimera(af.alignPanel, new PDBEntry[] - {}, new SequenceI[][] - {}); - initChimera("open " + chimeraSessionFile); - // TODO restore mappings + this.chimeraSessionFile = chimeraSession; + openNewChimera(alignPanel, pdbArray, seqsArray); + if (colourByChimera) + { + jmb.setColourBySequence(false); + seqColour.setSelected(false); + viewerColour.setSelected(true); + } + else if (colourBySequence) + { + jmb.setColourBySequence(true); + seqColour.setSelected(true); + viewerColour.setSelected(false); + } } /** @@ -433,18 +450,31 @@ public class ChimeraViewFrame extends StructureViewerBase return result; } - void initChimera(String command) + /** + * Launch Chimera. If we have a chimera session file name, send Chimera the + * command to open its saved session file. + */ + void initChimera() { jmb.setFinishedInit(false); - // TODO: consider waiting until the structure/view is fully loaded before - // displaying jalview.gui.Desktop.addInternalFrame(this, jmb.getViewerTitle("Chimera", true), getBounds().width, getBounds().height); - if (command == null) + + /* + * Pass an empty 'command' to launch Chimera + */ + jmb.evalStateCommand("", false); + + if (this.chimeraSessionFile != null) { - command = ""; + boolean opened = jmb.openSession(chimeraSessionFile); + if (!opened) + { + System.err + .println("An error occurred opening Chimera session file " + + chimeraSessionFile); + } } - jmb.evalStateCommand(command, false); jmb.setFinishedInit(true); } @@ -625,7 +655,7 @@ public class ChimeraViewFrame extends StructureViewerBase { try { - initChimera(""); + initChimera(); } catch (Exception ex) { Cache.log.error("Couldn't open Chimera viewer!", ex); @@ -986,7 +1016,7 @@ public class ChimeraViewFrame extends StructureViewerBase repaint(); return; } - setChainMenuItems(jmb.chainNames); + setChainMenuItems(jmb.getChainNames()); this.setTitle(jmb.getViewerTitle("Chimera", true)); if (jmb.getPdbFile().length > 1 && jmb.getSequence().length > 1) diff --git a/src/jalview/gui/Jalview2XML.java b/src/jalview/gui/Jalview2XML.java index bb4ef8b..728d2fc 100644 --- a/src/jalview/gui/Jalview2XML.java +++ b/src/jalview/gui/Jalview2XML.java @@ -27,6 +27,8 @@ import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceI; +import jalview.datamodel.ViewerData; +import jalview.datamodel.ViewerData.StructureData; import jalview.schemabinding.version2.AlcodMap; import jalview.schemabinding.version2.Alcodon; import jalview.schemabinding.version2.AlcodonFrame; @@ -100,6 +102,7 @@ import java.util.HashSet; import java.util.Hashtable; import java.util.IdentityHashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -128,47 +131,6 @@ import org.exolab.castor.xml.Unmarshaller; */ public class Jalview2XML { - - /** - * A data bean to hold stored data about a structure viewer. - */ - public class ViewerData - { - - private int x; - - private int y; - - private int width; - - private int height; - - public boolean alignWithPanel; - - public boolean colourWithAlignPanel; - - public boolean colourByViewer; - - String stateData = ""; - - // todo: java bean in place of Object [] - private Map fileData = new HashMap(); - - public ViewerData(int x, int y, int width, int height, - boolean alignWithPanel, boolean colourWithAlignPanel, - boolean colourByViewer) - { - this.x = x; - this.y = y; - this.width = width; - this.height = height; - this.alignWithPanel = alignWithPanel; - this.colourWithAlignPanel = colourWithAlignPanel; - this.colourByViewer = colourByViewer; - } - - } - /* * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps * of sequence objects are created. @@ -3073,9 +3035,11 @@ public class Jalview2XML protected void loadStructures(jarInputStreamProvider jprovider, JSeq[] jseqs, AlignFrame af, AlignmentPanel ap) { - // run through all PDB ids on the alignment, and collect mappings between - // jmol view ids and all sequences referring to it - Map jmolViewIds = new HashMap(); + /* + * Run through all PDB ids on the alignment, and collect mappings between + * distinct view ids and all sequences referring to that view. + */ + Map structureViewers = new LinkedHashMap(); for (int i = 0; i < jseqs.length; i++) { @@ -3115,9 +3079,9 @@ public class Jalview2XML sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width + "," + height; } - if (!jmolViewIds.containsKey(sviewid)) + if (!structureViewers.containsKey(sviewid)) { - jmolViewIds.put(sviewid, new ViewerData(x, y, width, height, + structureViewers.put(sviewid, new ViewerData(x, y, width, height, false, false, true)); // Legacy pre-2.7 conversion JAL-823 : // do not assume any view has to be linked for colour by @@ -3128,44 +3092,53 @@ public class Jalview2XML // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, { // seqs_file 2}, boolean[] { // linkAlignPanel,superposeWithAlignpanel}} from hash - ViewerData jmoldat = jmolViewIds.get(sviewid); - jmoldat.alignWithPanel |= structureState - .hasAlignwithAlignPanel() ? structureState.getAlignwithAlignPanel() : false; - // never colour by linked panel if not specified - jmoldat.colourWithAlignPanel |= structureState - .hasColourwithAlignPanel() ? structureState.getColourwithAlignPanel() - : false; - // default for pre-2.7 projects is that Jmol colouring is enabled - jmoldat.colourByViewer &= structureState + ViewerData jmoldat = structureViewers.get(sviewid); + jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel() + | (structureState.hasAlignwithAlignPanel() ? structureState + .getAlignwithAlignPanel() : false)); + + /* + * Default colour by linked panel to false if not specified (e.g. + * for pre-2.7 projects) + */ + boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel(); + colourWithAlignPanel |= (structureState + .hasColourwithAlignPanel() ? structureState + .getColourwithAlignPanel() : false); + jmoldat.setColourWithAlignPanel(colourWithAlignPanel); + + /* + * Default colour by viewer to true if not specified (e.g. for + * pre-2.7 projects) + */ + boolean colourByViewer = jmoldat.isColourByViewer(); + colourByViewer &= structureState .hasColourByJmol() ? structureState .getColourByJmol() : true; + jmoldat.setColourByViewer(colourByViewer); - if (jmoldat.stateData.length() < structureState.getContent() - .length()) + if (jmoldat.getStateData().length() < structureState + .getContent().length()) { { - jmoldat.stateData = structureState.getContent(); + jmoldat.setStateData(structureState.getContent()); } } if (ids[p].getFile() != null) { File mapkey = new File(ids[p].getFile()); - Object[] seqstrmaps = jmoldat.fileData.get(mapkey); + StructureData seqstrmaps = jmoldat.getFileData().get(mapkey); if (seqstrmaps == null) { - jmoldat.fileData.put(mapkey, - seqstrmaps = new Object[] - { pdbFile, ids[p].getId(), new Vector(), - new Vector() }); + jmoldat.getFileData().put( + mapkey, + seqstrmaps = jmoldat.new StructureData(pdbFile, + ids[p].getId())); } - if (!((Vector) seqstrmaps[2]).contains(seq)) + if (!seqstrmaps.getSeqList().contains(seq)) { - ((Vector) seqstrmaps[2]).addElement(seq); - // ((Vector)seqstrmaps[3]).addElement(n) : - // in principle, chains - // should be stored here : do we need to - // TODO: store and recover seq/pdb_id : - // chain mappings + seqstrmaps.getSeqList().add(seq); + // TODO and chains? } } else @@ -3178,7 +3151,7 @@ public class Jalview2XML } } // Instantiate the associated structure views - for (Entry entry : jmolViewIds.entrySet()) + for (Entry entry : structureViewers.entrySet()) { createOrLinkStructureViewer(entry, af, ap); } @@ -3212,7 +3185,7 @@ public class Jalview2XML * Pending an XML element for ViewerType, just check if stateData contains * "chimera" (part of the chimera session filename). */ - if (svattrib.stateData.indexOf("chimera") > -1) + if (svattrib.getStateData().indexOf("chimera") > -1) { createChimeraViewer(viewerData, af); } @@ -3232,36 +3205,34 @@ public class Jalview2XML AlignFrame af) { final ViewerData data = viewerData.getValue(); - String chimeraSession = data.stateData; - List pdbfilenames = new ArrayList(); - List seqmaps = new ArrayList(); - List pdbids = new ArrayList(); + String chimeraSession = data.getStateData(); if (new File(chimeraSession).exists()) { - Set> fileData = data.fileData.entrySet(); + Set> fileData = data.getFileData() + .entrySet(); List pdbs = new ArrayList(); List allseqs = new ArrayList(); - for (Entry pdb : fileData) - { - String filePath = (String) pdb.getValue()[0]; - String pdbId = (String) pdb.getValue()[1]; - final Vector seqList = (Vector) pdb.getValue()[2]; - PDBEntry pdbentry = new PDBEntry(); - pdbentry.setFile(filePath); - pdbentry.setId(pdbId); - pdbs.add(pdbentry); - SequenceI[] seqs = new SequenceI[seqList.size()]; - seqList.copyInto(seqs); + for (Entry pdb : fileData) + { + String filePath = pdb.getValue().getFilePath(); + String pdbId = pdb.getValue().getPdbId(); + pdbs.add(new PDBEntry(filePath, pdbId)); + final List seqList = pdb.getValue().getSeqList(); + SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]); allseqs.add(seqs); } + boolean colourByChimera = data.isColourByViewer(); + boolean colourBySequence = data.isColourWithAlignPanel(); + // TODO can/should this be done via StructureViewer (like Jmol)? final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs .size()]); final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs.size()][]); - ChimeraViewFrame cvf = // new ChimeraViewFrame(data, af); - new ChimeraViewFrame(af.alignPanel, pdbArray, seqsArray); + new ChimeraViewFrame(chimeraSession, af.alignPanel, pdbArray, + seqsArray, + colourByChimera, colourBySequence); } else { @@ -3282,13 +3253,13 @@ public class Jalview2XML final Entry viewerData, AlignFrame af) { final ViewerData svattrib = viewerData.getValue(); - String state = svattrib.stateData; + String state = svattrib.getStateData(); List pdbfilenames = new ArrayList(); List seqmaps = new ArrayList(); List pdbids = new ArrayList(); StringBuilder newFileLoc = new StringBuilder(64); int cp = 0, ncp, ecp; - Map oldFiles = svattrib.fileData; + Map oldFiles = svattrib.getFileData(); while ((ncp = state.indexOf("load ", cp)) > -1) { do @@ -3302,11 +3273,11 @@ public class Jalview2XML // have to normalize filename - since Jmol and jalview do // filename // translation differently. - Object[] filedat = oldFiles.get(new File(oldfilenam)); - newFileLoc.append(Platform.escapeString((String) filedat[0])); - pdbfilenames.add((String) filedat[0]); - pdbids.add((String) filedat[1]); - seqmaps.add(((Vector) filedat[2]) + StructureData filedat = oldFiles.get(new File(oldfilenam)); + newFileLoc.append(Platform.escapeString(filedat.getFilePath())); + pdbfilenames.add(filedat.getFilePath()); + pdbids.add(filedat.getPdbId()); + seqmaps.add(filedat.getSeqList() .toArray(new SequenceI[0])); newFileLoc.append("\""); cp = ecp + 1; // advance beyond last \" and set cursor so we can @@ -3327,15 +3298,14 @@ public class Jalview2XML { // add this and any other pdb files that should be present in // the viewer - Object[] filedat = oldFiles.get(id); - String nfilename; - newFileLoc.append(((String) filedat[0])); - pdbfilenames.add((String) filedat[0]); - pdbids.add((String) filedat[1]); - seqmaps.add(((Vector) filedat[2]) + StructureData filedat = oldFiles.get(id); + newFileLoc.append(filedat.getFilePath()); + pdbfilenames.add(filedat.getFilePath()); + pdbids.add(filedat.getPdbId()); + seqmaps.add(filedat.getSeqList() .toArray(new SequenceI[0])); newFileLoc.append(" \""); - newFileLoc.append((String) filedat[0]); + newFileLoc.append(filedat.getFilePath()); newFileLoc.append("\""); } @@ -3373,8 +3343,8 @@ public class Jalview2XML final String fileloc = newFileLoc.toString(); final String sviewid = viewerData.getKey(); final AlignFrame alf = af; - final java.awt.Rectangle rect = new java.awt.Rectangle(svattrib.x, - svattrib.y, svattrib.width, svattrib.height); + final Rectangle rect = new Rectangle(svattrib.getX(), + svattrib.getY(), svattrib.getWidth(), svattrib.getHeight()); try { javax.swing.SwingUtilities.invokeAndWait(new Runnable() @@ -3448,9 +3418,10 @@ public class Jalview2XML /* * Otherwise test for matching position and size of viewer frame */ - else if (frame.getX() == svattrib.x && frame.getY() == svattrib.y - && frame.getHeight() == svattrib.height - && frame.getWidth() == svattrib.width) + else if (frame.getX() == svattrib.getX() + && frame.getY() == svattrib.getY() + && frame.getHeight() == svattrib.getHeight() + && frame.getWidth() == svattrib.getWidth()) { comp = (AppJmol) frame; // todo: break? @@ -3476,10 +3447,10 @@ public class Jalview2XML // NOTE: if the jalview project is part of a shared session then // view synchronization should/could be done here. - final boolean useinViewerSuperpos = svattrib.alignWithPanel; - final boolean usetoColourbyseq = svattrib.colourWithAlignPanel; - final boolean viewerColouring = svattrib.colourByViewer; - Map oldFiles = svattrib.fileData; + final boolean useinViewerSuperpos = svattrib.isAlignWithPanel(); + final boolean usetoColourbyseq = svattrib.isColourWithAlignPanel(); + final boolean viewerColouring = svattrib.isColourByViewer(); + Map oldFiles = svattrib.getFileData(); /* * Add mapping for sequences in this view to an already open viewer @@ -3489,13 +3460,10 @@ public class Jalview2XML { // add this and any other pdb files that should be present in the // viewer - Object[] filedat = oldFiles.get(id); - String pdbFile = (String) filedat[0]; - SequenceI[] seq = ((Vector) filedat[2]) - .toArray(new SequenceI[0]); - binding - .getSsm() - .setMapping(seq, null, pdbFile, + StructureData filedat = oldFiles.get(id); + String pdbFile = filedat.getFilePath(); + SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]); + binding.getSsm().setMapping(seq, null, pdbFile, jalview.io.AppletFormatAdapter.FILE); binding.addSequenceForStructFile(pdbFile, seq); } diff --git a/src/jalview/gui/StructureViewer.java b/src/jalview/gui/StructureViewer.java index 7d986c8..b3b1962 100644 --- a/src/jalview/gui/StructureViewer.java +++ b/src/jalview/gui/StructureViewer.java @@ -24,7 +24,7 @@ import jalview.api.structures.JalviewStructureDisplayI; import jalview.bin.Cache; import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceI; -import jalview.gui.Jalview2XML.ViewerData; +import jalview.datamodel.ViewerData; import jalview.structure.StructureSelectionManager; import java.awt.Rectangle; @@ -135,16 +135,16 @@ public class StructureViewer AlignmentPanel alignPanel, ViewerData viewerData, String fileloc, Rectangle rect, String vid) { - final boolean useinViewerSuperpos = viewerData.alignWithPanel; - final boolean usetoColourbyseq = viewerData.colourWithAlignPanel; - final boolean viewerColouring = viewerData.colourByViewer; + final boolean useinViewerSuperpos = viewerData.isAlignWithPanel(); + final boolean usetoColourbyseq = viewerData.isColourWithAlignPanel(); + final boolean viewerColouring = viewerData.isColourByViewer(); JalviewStructureDisplayI sview = null; switch (type) { case JMOL: - sview = new AppJmol(pdbf, id, sq, alignPanel, useinViewerSuperpos, - usetoColourbyseq, viewerColouring, fileloc, rect, vid); + sview = new AppJmol(pdbf, id, sq, alignPanel, usetoColourbyseq, + useinViewerSuperpos, viewerColouring, fileloc, rect, vid); break; case CHIMERA: Cache.log.error("Unsupported structure viewer type " -- 1.7.10.2