chimodels = viewer.getChimeraModels();
// _modelFileNameMap = new int[chimodels.size()];
// int j = 0;
// for (ChimeraModel chimodel : chimodels)
// {
// String mdlName = chimodel.getModelName();
// }
// modelFileNames = new String[j];
// // System.arraycopy(mset, 0, modelFileNames, 0, j);
// }
return chimeraMaps.keySet().toArray(
modelFileNames = new String[chimeraMaps.size()]);
}
/**
* map from string to applet
*/
public Map getRegistryInfo()
{
// TODO Auto-generated method stub
return null;
}
/**
* returns the current sequenceRenderer that should be used to colour the
* structures
*
* @param alignment
*
* @return
*/
public abstract SequenceRenderer getSequenceRenderer(
AlignmentViewPanel alignment);
/**
* Construct and send a command to highlight an atom.
*
*
* Done by generating a command like (to 'highlight' position 44)
* ~select #0:43.C;select #0:44.C
* Note this removes the selection from the previous position.
*
*/
public void highlightAtom(int atomIndex, int pdbResNum, String chain,
String pdbfile)
{
List cms = chimeraMaps.get(pdbfile);
if (cms != null)
{
StringBuilder sb = new StringBuilder();
sb.append(" #" + cms.get(0).getModelNumber());
sb.append(":" + pdbResNum);
if (!chain.equals(" "))
{
sb.append("." + chain);
}
String atomSpec = sb.toString();
StringBuilder command = new StringBuilder(32);
if (lastMousedOverAtomSpec != null)
{
command.append("~show " + lastMousedOverAtomSpec + ";");
}
viewerCommandHistory(false);
command.append("show ").append(atomSpec);
String cmd = command.toString();
if (cmd.length() > 0)
{
viewer.sendChimeraCommand(cmd, false);
}
viewerCommandHistory(true);
this.lastMousedOverAtomSpec = atomSpec;
}
}
private void log(String message)
{
System.err.println("## Chimera log: " + message);
}
private void viewerCommandHistory(boolean enable)
{
// log("(Not yet implemented) History "
// + ((debug || enable) ? "on" : "off"));
}
public void loadInline(String string)
{
loadedInline = true;
// TODO: re JAL-623
// viewer.loadInline(strModel, isAppend);
// could do this:
// construct fake fullPathName and fileName so we can identify the file
// later.
// Then, construct pass a reader for the string to Jmol.
// ((org.jmol.Viewer.Viewer) viewer).loadModelFromFile(fullPathName,
// fileName, null, reader, false, null, null, 0);
// viewer.openStringInline(string);
log("cannot load inline in Chimera, yet");
}
public void mouseOverStructure(int atomIndex, String strInfo)
{
// function to parse a mouseOver event from Chimera
//
int pdbResNum;
int alocsep = strInfo.indexOf("^");
int mdlSep = strInfo.indexOf("/");
int chainSeparator = strInfo.indexOf(":"), chainSeparator1 = -1;
if (chainSeparator == -1)
{
chainSeparator = strInfo.indexOf(".");
if (mdlSep > -1 && mdlSep < chainSeparator)
{
chainSeparator1 = chainSeparator;
chainSeparator = mdlSep;
}
}
// handle insertion codes
if (alocsep != -1)
{
pdbResNum = Integer.parseInt(strInfo.substring(
strInfo.indexOf("]") + 1, alocsep));
}
else
{
pdbResNum = Integer.parseInt(strInfo.substring(
strInfo.indexOf("]") + 1, chainSeparator));
}
String chainId;
if (strInfo.indexOf(":") > -1)
{
chainId = strInfo.substring(strInfo.indexOf(":") + 1,
strInfo.indexOf("."));
}
else
{
chainId = " ";
}
String pdbfilename = modelFileNames[frameNo]; // default is first or current
// model
if (mdlSep > -1)
{
if (chainSeparator1 == -1)
{
chainSeparator1 = strInfo.indexOf(".", mdlSep);
}
String mdlId = (chainSeparator1 > -1) ? strInfo.substring(mdlSep + 1,
chainSeparator1) : strInfo.substring(mdlSep + 1);
try
{
// recover PDB filename for the model hovered over.
int _mp = _modelFileNameMap.length - 1, mnumber = new Integer(mdlId)
.intValue() - 1;
while (mnumber < _modelFileNameMap[_mp])
{
_mp--;
}
pdbfilename = modelFileNames[_mp];
if (pdbfilename == null)
{
// pdbfilename = new File(viewer.getModelFileName(mnumber))
// .getAbsolutePath();
}
} catch (Exception e)
{
}
;
}
if (lastMessage == null || !lastMessage.equals(strInfo))
{
getSsm().mouseOverStructure(pdbResNum, chainId, pdbfilename);
}
lastMessage = strInfo;
}
public void notifyAtomPicked(int atomIndex, String strInfo, String strData)
{
/**
* this implements the toggle label behaviour copied from the original
* structure viewer, MCView
*/
if (strData != null)
{
System.err.println("Ignoring additional pick data string " + strData);
}
// rewrite these selections for chimera (DNA, RNA and protein)
int chainSeparator = strInfo.indexOf(":");
int p = 0;
if (chainSeparator == -1)
{
chainSeparator = strInfo.indexOf(".");
}
String picked = strInfo.substring(strInfo.indexOf("]") + 1,
chainSeparator);
String mdlString = "";
if ((p = strInfo.indexOf(":")) > -1)
{
picked += strInfo.substring(p + 1, strInfo.indexOf("."));
}
if ((p = strInfo.indexOf("/")) > -1)
{
mdlString += strInfo.substring(p, strInfo.indexOf(" #"));
}
picked = "((" + picked + ".CA" + mdlString + ")|(" + picked + ".P"
+ mdlString + "))";
viewerCommandHistory(false);
if (!atomsPicked.contains(picked))
{
viewer.select(picked);
atomsPicked.add(picked);
}
else
{
viewer.select("not " + picked);
atomsPicked.remove(picked);
}
viewerCommandHistory(true);
// TODO: in application this happens
//
// if (scriptWindow != null)
// {
// scriptWindow.sendConsoleMessage(strInfo);
// scriptWindow.sendConsoleMessage("\n");
// }
}
// incremented every time a load notification is successfully handled -
// lightweight mechanism for other threads to detect when they can start
// referring to new structures.
private long loadNotifiesHandled = 0;
public long getLoadNotifiesHandled()
{
return loadNotifiesHandled;
}
public void notifyFileLoaded(String fullPathName, String fileName2,
String modelName, String errorMsg, int modelParts)
{
if (errorMsg != null)
{
fileLoadingError = errorMsg;
refreshGUI();
return;
}
// TODO: deal sensibly with models loaded inLine:
// modelName will be null, as will fullPathName.
// the rest of this routine ignores the arguments, and simply interrogates
// the Jmol view to find out what structures it contains, and adds them to
// the structure selection manager.
fileLoadingError = null;
String[] oldmodels = modelFileNames;
modelFileNames = null;
chainNames = new ArrayList();
chainFile = new HashMap();
boolean notifyLoaded = false;
String[] modelfilenames = getPdbFile();
// first check if we've lost any structures
if (oldmodels != null && oldmodels.length > 0)
{
int oldm = 0;
for (int i = 0; i < oldmodels.length; i++)
{
for (int n = 0; n < modelfilenames.length; n++)
{
if (modelfilenames[n] == oldmodels[i])
{
oldmodels[i] = null;
break;
}
}
if (oldmodels[i] != null)
{
oldm++;
}
}
if (oldm > 0)
{
String[] oldmfn = new String[oldm];
oldm = 0;
for (int i = 0; i < oldmodels.length; i++)
{
if (oldmodels[i] != null)
{
oldmfn[oldm++] = oldmodels[i];
}
}
// deregister the Jmol instance for these structures - we'll add
// ourselves again at the end for the current structure set.
getSsm().removeStructureViewerListener(this, oldmfn);
}
}
// register ourselves as a listener and notify the gui that it needs to
// update itself.
getSsm().addStructureViewerListener(this);
if (notifyLoaded)
{
FeatureRenderer fr = getFeatureRenderer(null);
if (fr != null)
{
fr.featuresAdded();
}
refreshGUI();
loadNotifiesHandled++;
}
setLoadingFromArchive(false);
}
public void setJalviewColourScheme(ColourSchemeI cs)
{
colourBySequence = false;
if (cs == null)
{
return;
}
int index;
Color col;
// Chimera expects RBG values in the range 0-1
final double normalise = 255D;
viewerCommandHistory(false);
// TODO: Switch between nucleotide or aa selection expressions
StringBuilder command = new StringBuilder(128);
command.append("color white;");
for (String res : ResidueProperties.aa3Hash.keySet())
{
index = ResidueProperties.aa3Hash.get(res).intValue();
if (index > 20)
{
continue;
}
col = cs.findColour(ResidueProperties.aa[index].charAt(0));
command.append("color " + col.getRed() / normalise + ","
+ col.getGreen() / normalise + "," + col.getBlue()
/ normalise + " ::" + res + ";");
}
evalStateCommand(command.toString(),false);
viewerCommandHistory(true);
}
/**
* called when the binding thinks the UI needs to be refreshed after a Chimera
* state change. this could be because structures were loaded, or because an
* error has occurred.
*/
public abstract void refreshGUI();
public void setLoadingFromArchive(boolean loadingFromArchive)
{
this.loadingFromArchive = loadingFromArchive;
}
/**
*
* @return true if Chimeral is still restoring state or loading is still going
* on (see setFinsihedLoadingFromArchive)
*/
public boolean isLoadingFromArchive()
{
return loadingFromArchive && !loadingFinished;
}
/**
* modify flag which controls if sequence colouring events are honoured by the
* binding. Should be true for normal operation
*
* @param finishedLoading
*/
public void setFinishedLoadingFromArchive(boolean finishedLoading)
{
loadingFinished = finishedLoading;
}
/**
* Send the Chimera 'background solid " command.
*
* @see https
* ://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/background
* .html
* @param col
*/
public void setBackgroundColour(Color col)
{
viewerCommandHistory(false);
double normalise = 255D;
final String command = "background solid " + col.getRed() / normalise + ","
+ col.getGreen() / normalise + "," + col.getBlue()
/ normalise + ";";
viewer.sendChimeraCommand(command, false);
viewerCommandHistory(true);
}
/**
*
* @param pdbfile
* @return text report of alignment between pdbfile and any associated
* alignment sequences
*/
public String printMapping(String pdbfile)
{
return getSsm().printMapping(pdbfile);
}
/**
* Ask Chimera to save its session to the given file. Returns true if
* successful, else false.
*
* @param filepath
* @return
*/
public boolean saveSession(String filepath)
{
if (isChimeraRunning())
{
List reply = viewer.sendChimeraCommand("save " + filepath,
true);
if (reply.contains("Session written"))
{
return true;
}
else
{
Cache.log
.error("Error saving Chimera session: " + reply.toString());
}
}
return false;
}
/**
* Ask Chimera to open a session file. Returns true if successful, else false.
* The filename must have a .py extension for this command to work.
*
* @param filepath
* @return
*/
public boolean openSession(String filepath)
{
evalStateCommand("open " + filepath, true);
// todo: test for failure - how?
return true;
}
public boolean isFinishedInit()
{
return finishedInit;
}
public void setFinishedInit(boolean finishedInit)
{
this.finishedInit = finishedInit;
}
public List getChainNames()
{
return chainNames;
}
}