import jalview.api.structures.JalviewStructureDisplayI;
import jalview.bin.Cache;
import jalview.datamodel.AlignmentI;
-import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.HiddenColumns;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SearchResultMatchI;
import jalview.datamodel.SearchResultsI;
private static final String ALPHACARBON = "CA";
- private List<String> chainNames = new ArrayList<String>();
+ private List<String> chainNames = new ArrayList<>();
+
+ private Hashtable<String, String> chainFile = new Hashtable<>();
- private Hashtable<String, String> chainFile = new Hashtable<String, String>();
-
/*
* Object through which we talk to Chimera
*/
/*
* Map of ChimeraModel objects keyed by PDB full local file name
*/
- private Map<String, List<ChimeraModel>> chimeraMaps = new LinkedHashMap<String, List<ChimeraModel>>();
+ private Map<String, List<ChimeraModel>> chimeraMaps = new LinkedHashMap<>();
String lastHighlightCommand;
/**
* 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.
+ * 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
String file = pe.getFile();
try
{
- List<ChimeraModel> modelsToMap = new ArrayList<ChimeraModel>();
- List<ChimeraModel> oldList = viewer.getModelList();
+ List<ChimeraModel> modelsToMap = new ArrayList<>();
+ List<ChimeraModel> oldList = viewer.isChimeraX() ? new ArrayList<>()
+ : viewer.getModelList();
boolean alreadyOpen = false;
/*
if (!alreadyOpen)
{
viewer.openModel(file, pe.getId(), ModelType.PDB_MODEL);
- List<ChimeraModel> newList = viewer.getModelList();
- // JAL-1728 newList.removeAll(oldList) does not work
- for (ChimeraModel cm : newList)
+ if (viewer.isChimeraX())
+ {
+ /*
+ * ChimeraX hack: force chimera model name to pdbId
+ */
+ int modelNumber = chimeraMaps.size() + 1;
+ String command = "setattr #" + modelNumber + " models name "
+ + pe.getId();
+ sendChimeraCommand(command, false);
+ modelsToMap.add(new ChimeraModel(pe.getId(), ModelType.PDB_MODEL,
+ modelNumber, 0));
+ }
+ else
{
- if (cm.getModelName().equals(pe.getId()))
+ /*
+ * Chimera: query for actual models and find the one with
+ * matching model name - set in viewer.openModel()
+ */
+ List<ChimeraModel> newList = viewer.getModelList();
+ // JAL-1728 newList.removeAll(oldList) does not work
+ for (ChimeraModel cm : newList)
{
- modelsToMap.add(cm);
+ if (cm.getModelName().equals(pe.getId()))
+ {
+ modelsToMap.add(cm);
+ }
}
}
}
* @param protocol
*/
public JalviewChimeraBinding(StructureSelectionManager ssm,
- PDBEntry[] pdbentry, SequenceI[][] sequenceIs, DataSourceType protocol)
+ PDBEntry[] pdbentry, SequenceI[][] sequenceIs,
+ DataSourceType protocol)
{
super(ssm, pdbentry, sequenceIs, protocol);
viewer = new ChimeraManager(new StructureManager(true));
}
/**
- * Starts a thread that waits for the Chimera process to finish, so that we
- * can then close the associated resources. This avoids leaving orphaned
- * Chimera viewer panels in Jalview if the user closes Chimera.
+ * Starts a thread that waits for the Chimera process to finish, so that we can
+ * then close the associated resources. This avoids leaving orphaned Chimera
+ * viewer panels in Jalview if the user closes Chimera.
*/
protected void startChimeraProcessMonitor()
{
}
/**
- * Start a dedicated HttpServer to listen for Chimera notifications, and tell
- * it to start listening
+ * Start a dedicated HttpServer to listen for Chimera notifications, and tell it
+ * to start listening
*/
public void startChimeraListener()
{
viewer.startListening(chimeraListener.getUri());
} catch (BindException e)
{
- System.err.println("Failed to start Chimera listener: "
- + e.getMessage());
+ System.err.println(
+ "Failed to start Chimera listener: " + e.getMessage());
}
}
for (String chain : toshow)
{
int modelNumber = getModelNoForChain(chain);
- String showChainCmd = modelNumber == -1 ? "" : modelNumber + ":."
- + chain.split(":")[1];
+ String showChainCmd = modelNumber == -1 ? ""
+ : modelNumber + ":." + chain.split(":")[1];
if (!first)
{
cmd.append(",");
*/
public void closeViewer(boolean closeChimera)
{
- getSsm().removeStructureViewerListener(this, this.getPdbFile());
+ getSsm().removeStructureViewerListener(this, this.getStructureFiles());
if (closeChimera)
{
viewer.exitChimera();
*/
@Override
public String superposeStructures(AlignmentI[] _alignment,
- int[] _refStructure, ColumnSelection[] _hiddenCols)
+ int[] _refStructure, HiddenColumns[] _hiddenCols)
{
StringBuilder allComs = new StringBuilder(128);
- String[] files = getPdbFile();
+ String[] files = getStructureFiles();
if (!waitForFileLoad(files))
{
{
int refStructure = _refStructure[a];
AlignmentI alignment = _alignment[a];
- ColumnSelection hiddenCols = _hiddenCols[a];
+ HiddenColumns hiddenCols = _hiddenCols[a];
if (refStructure >= files.length)
{
if (debug)
{
System.out.println("Select regions:\n" + selectioncom.toString());
- System.out.println("Superimpose command(s):\n"
- + command.toString());
+ System.out.println(
+ "Superimpose command(s):\n" + command.toString());
}
allComs.append("~display all; chain @CA|P; ribbon ")
.append(selectioncom.toString())
* to the Chimera command 'list models type molecule', see
* ChimeraManager.getModelList().
*/
- List<ChimeraModel> maps = chimeraMaps.get(getPdbFile()[pdbfnum]);
+ List<ChimeraModel> maps = chimeraMaps.get(getStructureFiles()[pdbfnum]);
boolean hasSubModels = maps != null && maps.size() > 1;
return "#" + String.valueOf(pdbfnum) + (hasSubModels ? ".1" : "");
}
return true;
}
- boolean launched = viewer.launchChimera(StructureManager
- .getChimeraPaths());
+ boolean launched = viewer
+ .launchChimera(StructureManager.getChimeraPaths());
if (launched)
{
startChimeraProcessMonitor();
String[] files, SequenceRenderer sr, AlignmentViewPanel viewPanel)
{
return ChimeraCommands.getColourBySequenceCommand(getSsm(), files,
- getSequence(), sr, viewPanel);
+ getSequence(), sr, viewPanel, viewer.isChimeraX());
}
/**
*/
private int _modelFileNameMap[];
-
// ////////////////////////////////
// /StructureListener
@Override
- public synchronized String[] getPdbFile()
+ public synchronized String[] getStructureFiles()
{
if (viewer == null)
{
return new String[0];
}
- return chimeraMaps.keySet().toArray(
- modelFileNames = new String[chimeraMaps.size()]);
+ return chimeraMaps.keySet()
+ .toArray(modelFileNames = new String[chimeraMaps.size()]);
}
/**
- * Construct and send a command to highlight zero, one or more atoms. We do
- * this by sending an "rlabel" command to show the residue label at that
- * position.
+ * Construct and send a command to highlight zero, one or more atoms. We do this
+ * by sending an "rlabel" command to show the residue label at that position.
*/
@Override
public void highlightAtoms(List<AtomSpec> atoms)
return;
}
+ boolean forChimeraX = viewer.isChimeraX();
StringBuilder cmd = new StringBuilder(128);
boolean first = true;
boolean found = false;
{
if (first)
{
- cmd.append("rlabel #").append(cms.get(0).getModelNumber())
- .append(":");
+ cmd.append(forChimeraX ? "label #" : "rlabel #");
}
else
{
cmd.append(",");
}
first = false;
- cmd.append(pdbResNum);
- if (!chain.equals(" "))
+ if (forChimeraX)
+ {
+ cmd.append(cms.get(0).getModelNumber())
+ .append("/").append(chain).append(":").append(pdbResNum);
+ }
+ else
{
- cmd.append(".").append(chain);
+ cmd.append(cms.get(0).getModelNumber())
+ .append(":").append(pdbResNum);
+ if (!chain.equals(" ") && !forChimeraX)
+ {
+ cmd.append(".").append(chain);
+ }
}
found = true;
}
* Parse model number, residue and chain for each selected position,
* formatted as #0:123.A or #1.2:87.B (#model.submodel:residue.chain)
*/
- List<AtomSpec> atomSpecs = convertStructureResiduesToAlignment(selection);
+ List<AtomSpec> atomSpecs = convertStructureResiduesToAlignment(
+ selection);
/*
* Broadcast the selection (which may be empty, if the user just cleared all
protected List<AtomSpec> convertStructureResiduesToAlignment(
List<String> structureSelection)
{
- List<AtomSpec> atomSpecs = new ArrayList<AtomSpec>();
+ List<AtomSpec> atomSpecs = new ArrayList<>();
for (String atomSpec : structureSelection)
{
try
false);
for (String resName : residueSet)
{
- char res = resName.length() == 3 ? ResidueProperties
- .getSingleCharacterCode(resName) : resName.charAt(0);
+ char res = resName.length() == 3
+ ? ResidueProperties.getSingleCharacterCode(resName)
+ : resName.charAt(0);
Color col = cs.findColour(res, 0, null, null, 0f);
command.append("color " + col.getRed() / normalise + ","
- + col.getGreen() / normalise + "," + col.getBlue()
- / normalise + " ::" + resName + ";");
+ + col.getGreen() / normalise + "," + col.getBlue() / normalise
+ + " ::" + resName + ";");
}
sendAsynchronousCommand(command.toString(), COLOURING_CHIMERA);
/**
* Send the Chimera 'background solid <color>" command.
*
- * @see https
+ * @see https
* ://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/background
* .html
* @param col
viewerCommandHistory(false);
double normalise = 255D;
final String command = "background solid " + col.getRed() / normalise
- + "," + col.getGreen() / normalise + "," + col.getBlue()
- / normalise + ";";
+ + "," + col.getGreen() / normalise + ","
+ + col.getBlue() / normalise + ";";
viewer.sendChimeraCommand(command, false);
viewerCommandHistory(true);
}
// TODO refactor as required to pull up to an interface
AlignmentI alignment = avp.getAlignment();
- String[] files = getPdbFile();
+ String[] files = getStructureFiles();
if (files == null)
{
return 0;
StructureMappingcommandSet commandSet = ChimeraCommands
.getSetAttributeCommandsForFeatures(getSsm(), files,
- getSequence(), avp);
+ getSequence(), avp, viewer.isChimeraX());
String[] commands = commandSet.commands;
if (commands.length > 10)
{
}
/**
- * Write commands to a temporary file, and send a command to Chimera to open
- * the file as a commands script. For use when sending a large number of
- * separate commands would overload the REST interface mechanism.
+ * Write commands to a temporary file, and send a command to Chimera to open the
+ * file as a commands script. For use when sending a large number of separate
+ * commands would overload the REST interface mechanism.
*
* @param commands
*/
protected void sendCommandsByFile(String[] commands)
{
+ boolean toChimeraX = viewer.isChimeraX();
try
{
- File tmp = File.createTempFile("chim", ".com");
+ File tmp = File.createTempFile("chim", toChimeraX ? ".cxc" : ".com");
tmp.deleteOnExit();
PrintWriter out = new PrintWriter(new FileOutputStream(tmp));
for (String command : commands)
out.flush();
out.close();
String path = tmp.getAbsolutePath();
- sendAsynchronousCommand("open cmd:" + path, null);
+ String command = "open " + (toChimeraX ? "" : "cmd:") + path;
+ sendAsynchronousCommand(command, null);
} catch (IOException e)
{
- System.err
- .println("Sending commands to Chimera via file failed with "
- + e.getMessage());
+ System.err.println("Sending commands to Chimera via file failed with "
+ + e.getMessage());
}
}
return CHIMERA_FEATURE_GROUP;
}
-
public Hashtable<String, String> getChainFile()
{
return chainFile;