releaseUIResources();
}
- /**
- * superpose the structures associated with sequences in the alignment
- * according to their corresponding positions.
- *
- * @deprecated not used - remove?
- */
- @Deprecated
- public void superposeStructures(AlignmentI alignment)
- {
- superposeStructures(alignment, -1, null);
- }
-
- /**
- * superpose the structures associated with sequences in the alignment
- * according to their corresponding positions. ded)
- *
- * @param refStructure
- * - select which pdb file to use as reference (default is -1 - the
- * first structure in the alignment)
- * @deprecated not used - remove?
- */
- @Deprecated
- public void superposeStructures(AlignmentI alignment, int refStructure)
- {
- superposeStructures(alignment, refStructure, null);
- }
-
- /**
- * superpose the structures associated with sequences in the alignment
- * according to their corresponding positions. ded)
- *
- * @param refStructure
- * - select which pdb file to use as reference (default is -1 - the
- * first structure in the alignment)
- * @param hiddenCols
- * TODO
- * @deprecated not used - remove?
- */
- @Deprecated
- public void superposeStructures(AlignmentI alignment, int refStructure,
- HiddenColumns hiddenCols)
- {
- superposeStructures(new AlignmentI[] { alignment },
- new int[]
- { refStructure }, new HiddenColumns[] { hiddenCols });
- }
-
- /**
- * {@inheritDoc}
- */
- public String superposeStructures(AlignmentI[] _alignment,
- int[] _refStructure, HiddenColumns[] _hiddenCols)
- {
- // TODO delete method
- while (jmolViewer.isScriptExecuting())
- {
- try
- {
- Thread.sleep(10);
- } catch (InterruptedException i)
- {
- }
- }
-
- /*
- * get the distinct structure files modelled
- * (a file with multiple chains may map to multiple sequences)
- */
- String[] files = getStructureFiles();
- if (!waitForFileLoad(files))
- {
- return null;
- }
-
- StringBuilder selectioncom = new StringBuilder(256);
- // In principle - nSeconds specifies the speed of animation for each
- // superposition - but is seems to behave weirdly, so we don't specify it.
- String nSeconds = " ";
- if (files.length > 10)
- {
- nSeconds = " 0.005 ";
- }
- else
- {
- nSeconds = " " + (2.0 / files.length) + " ";
- // if (nSeconds).substring(0,5)+" ";
- }
-
- // see JAL-1345 - should really automatically turn off the animation for
- // large numbers of structures, but Jmol doesn't seem to allow that.
- // nSeconds = " ";
- // union of all aligned positions are collected together.
- for (int a = 0; a < _alignment.length; a++)
- {
- int refStructure = _refStructure[a];
- AlignmentI alignment = _alignment[a];
- HiddenColumns hiddenCols = _hiddenCols[a];
- if (a > 0 && selectioncom.length() > 0 && !selectioncom
- .substring(selectioncom.length() - 1).equals("|"))
- {
- selectioncom.append("|");
- }
- // process this alignment
- if (refStructure >= files.length)
- {
- System.err.println(
- "Invalid reference structure value " + refStructure);
- refStructure = -1;
- }
-
- /*
- * 'matched' bit j will be set for visible alignment columns j where
- * all sequences have a residue with a mapping to the PDB structure
- */
- BitSet matched = new BitSet();
- for (int m = 0; m < alignment.getWidth(); m++)
- {
- if (hiddenCols == null || hiddenCols.isVisible(m))
- {
- matched.set(m);
- }
- }
-
- SuperposeData[] structures = new SuperposeData[files.length];
- for (int f = 0; f < files.length; f++)
- {
- structures[f] = new SuperposeData(alignment.getWidth(), f);
- }
-
- /*
- * Calculate the superposable alignment columns ('matched'), and the
- * corresponding structure residue positions (structures.pdbResNo)
- */
- int candidateRefStructure = findSuperposableResidues(alignment,
- matched, structures);
- if (refStructure < 0)
- {
- /*
- * If no reference structure was specified, pick the first one that has
- * a mapping in the alignment
- */
- refStructure = candidateRefStructure;
- }
-
- String[] selcom = new String[files.length];
- int nmatched = matched.cardinality();
- if (nmatched < 4)
- {
- return (MessageManager.formatMessage("label.insufficient_residues",
- nmatched));
- }
-
- /*
- * generate select statements to select regions to superimpose structures
- */
- {
- // TODO extract method to construct selection statements
- for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
- {
- String chainCd = ":" + structures[pdbfnum].chain;
- int lpos = -1;
- boolean run = false;
- StringBuilder molsel = new StringBuilder();
- molsel.append("{");
-
- int nextColumnMatch = matched.nextSetBit(0);
- while (nextColumnMatch != -1)
- {
- int pdbResNo = structures[pdbfnum].pdbResNo[nextColumnMatch];
- if (lpos != pdbResNo - 1)
- {
- // discontinuity
- if (lpos != -1)
- {
- molsel.append(lpos);
- molsel.append(chainCd);
- molsel.append("|");
- }
- run = false;
- }
- else
- {
- // continuous run - and lpos >-1
- if (!run)
- {
- // at the beginning, so add dash
- molsel.append(lpos);
- molsel.append("-");
- }
- run = true;
- }
- lpos = pdbResNo;
- nextColumnMatch = matched.nextSetBit(nextColumnMatch + 1);
- }
- /*
- * add final selection phrase
- */
- if (lpos != -1)
- {
- molsel.append(lpos);
- molsel.append(chainCd);
- molsel.append("}");
- }
- if (molsel.length() > 1)
- {
- selcom[pdbfnum] = molsel.toString();
- selectioncom.append("((");
- selectioncom.append(selcom[pdbfnum].substring(1,
- selcom[pdbfnum].length() - 1));
- selectioncom.append(" )& ");
- selectioncom.append(pdbfnum + 1);
- selectioncom.append(".1)");
- if (pdbfnum < files.length - 1)
- {
- selectioncom.append("|");
- }
- }
- else
- {
- selcom[pdbfnum] = null;
- }
- }
- }
- StringBuilder command = new StringBuilder(256);
- // command.append("set spinFps 10;\n");
-
- for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
- {
- if (pdbfnum == refStructure || selcom[pdbfnum] == null
- || selcom[refStructure] == null)
- {
- continue;
- }
- command.append("echo ");
- command.append("\"Superposing (");
- command.append(structures[pdbfnum].pdbId);
- command.append(") against reference (");
- command.append(structures[refStructure].pdbId);
- command.append(")\";\ncompare " + nSeconds);
- command.append("{");
- command.append(Integer.toString(1 + pdbfnum));
- command.append(".1} {");
- command.append(Integer.toString(1 + refStructure));
- // conformation=1 excludes alternate locations for CA (JAL-1757)
- command.append(
- ".1} SUBSET {(*.CA | *.P) and conformation=1} ATOMS ");
-
- // for (int s = 0; s < 2; s++)
- // {
- // command.append(selcom[(s == 0 ? pdbfnum : refStructure)]);
- // }
- command.append(selcom[pdbfnum]);
- command.append(selcom[refStructure]);
- command.append(" ROTATE TRANSLATE;\n");
- }
- if (selectioncom.length() > 0)
- {
- String cmdString = command.toString();
- executeCommand(cmdString, false);
- }
- }
- if (selectioncom.length() > 0)
- {
- /*
- * finally, highlight with cartoons the residues that were superposed
- */
- if (selectioncom.charAt(selectioncom.length() - 1) == '|')
- {
- selectioncom.setLength(selectioncom.length() - 1);
- }
- executeCommand("select *; cartoons off; backbone; select ("
- + selectioncom.toString() + "); cartoons; ", false);
- }
-
- return null;
- }
-
@Override
public List<String> executeCommand(String command, boolean getReply)
{
}
/**
- * {@inheritDoc}
- */
- public String superposeStructures(AlignmentI[] _alignment,
- int[] _refStructure, HiddenColumns[] _hiddenCols)
- {
- // TODO delete method
- StringBuilder allComs = new StringBuilder(128);
- String[] files = getStructureFiles();
-
- if (!waitForFileLoad(files))
- {
- return null;
- }
-
- refreshPdbEntries();
- StringBuilder selectioncom = new StringBuilder(256);
- boolean chimeraX = chimeraManager.isChimeraX();
- for (int a = 0; a < _alignment.length; a++)
- {
- int refStructure = _refStructure[a];
- AlignmentI alignment = _alignment[a];
- HiddenColumns hiddenCols = _hiddenCols[a];
-
- if (refStructure >= files.length)
- {
- System.err.println("Ignoring invalid reference structure value "
- + refStructure);
- refStructure = -1;
- }
-
- /*
- * 'matched' bit i will be set for visible alignment columns i where
- * all sequences have a residue with a mapping to the PDB structure
- */
- BitSet matched = new BitSet();
- for (int m = 0; m < alignment.getWidth(); m++)
- {
- if (hiddenCols == null || hiddenCols.isVisible(m))
- {
- matched.set(m);
- }
- }
-
- SuperposeData[] structures = new SuperposeData[files.length];
- for (int f = 0; f < files.length; f++)
- {
- structures[f] = new SuperposeData(alignment.getWidth(), f);
- }
-
- /*
- * Calculate the superposable alignment columns ('matched'), and the
- * corresponding structure residue positions (structures.pdbResNo)
- */
- int candidateRefStructure = findSuperposableResidues(alignment,
- matched, structures);
- if (refStructure < 0)
- {
- /*
- * If no reference structure was specified, pick the first one that has
- * a mapping in the alignment
- */
- refStructure = candidateRefStructure;
- }
-
- int nmatched = matched.cardinality();
- if (nmatched < 4)
- {
- return MessageManager.formatMessage("label.insufficient_residues",
- nmatched);
- }
-
- /*
- * Generate select statements to select regions to superimpose structures
- */
- String[] selcom = new String[files.length];
- for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
- {
- final int modelNo = pdbfnum + (chimeraX ? 1 : 0);
- // todo correct resolution to model number
- String chainCd = "." + structures[pdbfnum].chain;
- int lpos = -1;
- boolean run = false;
- StringBuilder molsel = new StringBuilder();
- if (chimeraX)
- {
- molsel.append("/" + structures[pdbfnum].chain + ":");
- }
-
- int nextColumnMatch = matched.nextSetBit(0);
- while (nextColumnMatch != -1)
- {
- int pdbResNum = structures[pdbfnum].pdbResNo[nextColumnMatch];
- if (lpos != pdbResNum - 1)
- {
- /*
- * discontiguous - append last residue now
- */
- if (lpos != -1)
- {
- molsel.append(String.valueOf(lpos));
- if (!chimeraX)
- {
- molsel.append(chainCd);
- }
- molsel.append(",");
- }
- run = false;
- }
- else
- {
- /*
- * extending a contiguous run
- */
- if (!run)
- {
- /*
- * start the range selection
- */
- molsel.append(String.valueOf(lpos));
- molsel.append("-");
- }
- run = true;
- }
- lpos = pdbResNum;
- nextColumnMatch = matched.nextSetBit(nextColumnMatch + 1);
- }
-
- /*
- * and terminate final selection
- */
- if (lpos != -1)
- {
- molsel.append(String.valueOf(lpos));
- if (!chimeraX)
- {
- molsel.append(chainCd);
- }
- }
- if (molsel.length() > 1)
- {
- selcom[pdbfnum] = molsel.toString();
- selectioncom.append("#").append(String.valueOf(modelNo));
- if (!chimeraX)
- {
- selectioncom.append(":");
- }
- selectioncom.append(selcom[pdbfnum]);
- // selectioncom.append(" ");
- if (pdbfnum < files.length - 1)
- {
- selectioncom.append("|");
- }
- }
- else
- {
- selcom[pdbfnum] = null;
- }
- }
-
- StringBuilder command = new StringBuilder(256);
- for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
- {
- final int modelNo = pdbfnum + (chimeraX ? 1 : 0);
- if (pdbfnum == refStructure || selcom[pdbfnum] == null
- || selcom[refStructure] == null)
- {
- continue;
- }
- if (command.length() > 0)
- {
- command.append(";");
- }
-
- /*
- * Form Chimera match command, from the 'new' structure to the
- * 'reference' structure e.g. (50 residues, chain B/A, alphacarbons):
- *
- * 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
- */
- command.append(chimeraX ? "align " : "match ");
- command.append(getModelSpec(modelNo));
- if (!chimeraX)
- {
- command.append(":");
- }
- command.append(selcom[pdbfnum]);
- command.append("@").append(
- structures[pdbfnum].isRna ? PHOSPHORUS : ALPHACARBON);
- // JAL-1757 exclude alternate CA locations - ChimeraX syntax tbd
- if (!chimeraX)
- {
- command.append(NO_ALTLOCS);
- }
- command.append(chimeraX ? " toAtoms " : " ")
- .append(getModelSpec(refStructure + (chimeraX ? 1 : 0)));
- if (!chimeraX)
- {
- command.append(":");
- }
- command.append(selcom[refStructure]);
- command.append("@").append(
- structures[refStructure].isRna ? PHOSPHORUS : ALPHACARBON);
- if (!chimeraX)
- {
- command.append(NO_ALTLOCS);
- }
- }
- if (selectioncom.length() > 0)
- {
- if (debug)
- {
- System.out.println("Select regions:\n" + selectioncom.toString());
- System.out.println(
- "Superimpose command(s):\n" + command.toString());
- }
- // allComs.append("~display all; ");
- // if (chimeraX)
- // {
- // allComs.append("show ").append(selectioncom.toString())
- // .append(" pbonds");
- // }
- // else
- // {
- // allComs.append("chain @CA|P; ribbon ");
- // allComs.append(selectioncom.toString());
- // }
- if (allComs.length() > 0) {
- allComs.append(";");
- }
- allComs.append(command.toString());
- }
- }
-
- String error = null;
- if (selectioncom.length() > 0)
- {
- // TODO: visually distinguish regions that were superposed
- if (selectioncom.substring(selectioncom.length() - 1).equals("|"))
- {
- selectioncom.setLength(selectioncom.length() - 1);
- }
- if (debug)
- {
- System.out.println("Select regions:\n" + selectioncom.toString());
- }
- allComs.append(";~display all; ");
- if (chimeraX)
- {
- allComs.append("show @CA|P pbonds; show ")
- .append(selectioncom.toString()).append(" ribbons; view");
- }
- else
- {
- allComs.append("chain @CA|P; ribbon ");
- allComs.append(selectioncom.toString()).append("; focus");
- }
- // allComs.append("; ~display all; chain @CA|P; ribbon ")
- // .append(selectioncom.toString()).append("; focus");
- List<String> chimeraReplies = executeCommand(allComs.toString(),
- true);
- for (String reply : chimeraReplies)
- {
- if (reply.toLowerCase().contains("unequal numbers of atoms"))
- {
- error = reply;
- }
- }
- }
- return error;
- }
-
- /**
* Helper method to construct model spec in Chimera format:
* <ul>
* <li>#0 (#1 etc) for a PDB file with no sub-models</li>