superposeStructures(AtomSpecModel ref,
AtomSpecModel spec, AtomSpecType backbone)
{
/*
* Form Chimera match command to match spec to ref
* (the first set of atoms are moved on to the second)
*
* match #1:1-30.B,81-100.B@CA #0:21-40.A,61-90.A@CA
*
* @see https://www.cgl.ucsf.edu/chimera/docs/UsersGuide/midas/match.html
*/
StringBuilder cmd = new StringBuilder();
String atomSpecAlphaOnly = getAtomSpec(spec, backbone);
String refSpecAlphaOnly = getAtomSpec(ref, backbone);
cmd.append("match ").append(atomSpecAlphaOnly).append(" ")
.append(refSpecAlphaOnly);
/*
* show superposed residues as ribbon
*/
String atomSpec = getAtomSpec(spec, AtomSpecType.RESIDUE_ONLY);
String refSpec = getAtomSpec(ref, AtomSpecType.RESIDUE_ONLY);
cmd.append("; ribbon ");
cmd.append(atomSpec).append("|").append(refSpec).append("; focus");
return Arrays.asList(new StructureCommand(cmd.toString()));
}
@Override
public StructureCommandI openCommandFile(String path)
{
// https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/filetypes.html
return new StructureCommand("open cmd:" + path);
}
@Override
public StructureCommandI saveSession(String filepath)
{
// https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/save.html
return new StructureCommand("save " + filepath);
}
/**
* Returns the range(s) modelled by {@code atomSpec} formatted as a Chimera
* atomspec string, e.g.
*
*
* #0:15.A,28.A,54.A,70-72.A|#1:2.A,6.A,11.A,13-14.A
*
*
* where
*
* - #0 is a model number
* - 15 or 70-72 is a residue number, or range of residue numbers
* - .A is a chain identifier
* - residue ranges are separated by comma
* - atomspecs for distinct models are separated by | (or)
*
*
*
*
* @param model
* @param specType
* @return
* @see https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/frameatom_spec.html
*/
@Override
public String getAtomSpec(AtomSpecModel atomSpec, AtomSpecType specType)
{
StringBuilder sb = new StringBuilder(128);
boolean firstModel = true;
for (String model : atomSpec.getModels())
{
if (!firstModel)
{
sb.append("|");
}
firstModel = false;
appendModel(sb, model, atomSpec, specType);
}
return sb.toString();
}
/**
* A helper method to append an atomSpec string for atoms in the given model
*
* @param sb
* @param model
* @param atomSpec
* @param alphaOnly
*/
protected void appendModel(StringBuilder sb, String model,
AtomSpecModel atomSpec, AtomSpecType specType)
{
sb.append("#").append(model).append(":");
boolean firstPositionForModel = true;
for (String chain : atomSpec.getChains(model))
{
chain = " ".equals(chain) ? chain : chain.trim();
List rangeList = atomSpec.getRanges(model, chain);
for (int[] range : rangeList)
{
appendRange(sb, range[0], range[1], chain, firstPositionForModel,
false);
firstPositionForModel = false;
}
}
if (specType == AtomSpecType.ALPHA)
{
/*
* restrict to alpha carbon, no alternative locations
* (needed to ensuring matching atom counts for superposition)
*/
sb.append("@CA").append(NO_ALTLOCS);
}
if (specType == AtomSpecType.PHOSPHATE)
{
sb.append("@P").append(NO_ALTLOCS);
}
}
@Override
public List showBackbone()
{
return Arrays.asList(SHOW_BACKBONE);
}
@Override
public StructureCommandI loadFile(String file)
{
return new StructureCommand("open " + file);
}
@Override
public StructureCommandI openSession(String filepath)
{
// https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/filetypes.html
// this version of the command has no dependency on file extension
return new StructureCommand("open chimera:" + filepath);
}
@Override
public StructureCommandI closeViewer()
{
return CLOSE_CHIMERA;
}
@Override
public List startNotifications(String uri)
{
// https://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/midas/listen.html
List cmds = new ArrayList<>();
cmds.add(new StructureCommand("listen start models url " + uri));
cmds.add(new StructureCommand(
"listen start select prefix SelectionChanged url " + uri));
return cmds;
}
@Override
public List stopNotifications()
{
List cmds = new ArrayList<>();
cmds.add(STOP_NOTIFY_MODELS);
cmds.add(STOP_NOTIFY_SELECTION);
return cmds;
}
@Override
public StructureCommandI getSelectedResidues()
{
return GET_SELECTION;
}
@Override
public StructureCommandI listResidueAttributes()
{
return LIST_RESIDUE_ATTRIBUTES;
}
@Override
public StructureCommandI getResidueAttributes(String attName)
{
// this alternative command
// list residues spec ':*/attName' attr attName
// doesn't report 'None' values (which is good), but
// fails for 'average.bfactor' (which is bad):
return new StructureCommand("list residues attr '" + attName + "'");
}
@Override
public List centerViewOn(List residues)
{
// TODO Auto-generated method stub
return null;
}
}