From: Peter Murray-R. <pe...@us...> - 2006-06-27 17:08:04
|
Update of /cvsroot/cml/jumbo53/src/org/xmlcml/cml/tools In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv5151/src/org/xmlcml/cml/tools Modified Files: CrystalTool.java PolymerTool.java Added Files: FragmentSequence.java Log Message: main polymer and cml frag routines Index: PolymerTool.java =================================================================== RCS file: /cvsroot/cml/jumbo53/src/org/xmlcml/cml/tools/PolymerTool.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** PolymerTool.java 23 Jun 2006 15:33:05 -0000 1.3 --- PolymerTool.java 27 Jun 2006 17:07:26 -0000 1.4 *************** *** 13,19 **** --- 13,24 ---- import org.xmlcml.cml.element.CMLArg; import org.xmlcml.cml.element.CMLAtom; + import org.xmlcml.cml.element.CMLAtomArray; import org.xmlcml.cml.element.CMLBond; + import org.xmlcml.cml.element.CMLBondArray; import org.xmlcml.cml.element.CMLJoin; + import org.xmlcml.cml.element.CMLLength; import org.xmlcml.cml.element.CMLMolecule; + import org.xmlcml.cml.element.CMLTorsion; + import org.xmlcml.cml.element.CMLZMatrix; *************** *** 48,51 **** --- 53,60 ---- public static final String PML_COMPLETE = "cml:PML-complete"; + /** cartesians added. + */ + public static final String PML_CARTESIAN = "cml:PML-cartesian"; + /** branch attribute. */ *************** *** 85,88 **** --- 94,99 ---- } else if (convention.equals(PML_EXPLICIT)) { processExplicit(); + } else if (convention.equals(PML_COMPLETE)) { + processZMatrix(); } } *************** *** 98,102 **** formula = formula.replace(S_NEWLINE, S_EMPTY); formula = formula.replace(S_SPACE, S_EMPTY); ! FragmentSequence fragmentSequence = FragmentAndBond.processConcise1(formula); CMLJoin topJoin = fragmentSequence.getCMLJoin(); molecule.appendChild(topJoin); --- 109,114 ---- formula = formula.replace(S_NEWLINE, S_EMPTY); formula = formula.replace(S_SPACE, S_EMPTY); ! // FragmentSequence fragmentSequence = FragmentAndBond.processConcise1(formula); ! FragmentSequence fragmentSequence = new FragmentSequence(formula); CMLJoin topJoin = fragmentSequence.getCMLJoin(); molecule.appendChild(topJoin); *************** *** 114,127 **** expandCountExpressions(); ! molecule.debug(); ! System.out.println("============================="); ! // add args first so every molecule has unique id ! addArgs(join.query(".//*[local-name()='molecule' and @ref]")); // create join/@atomRefs2 join.processChildMolecules(); ! System.out.println("---------------------------"); // molecule.debug(); // remove all joins not join/@atomRefs2 removeNonAtomRefs2(join); --- 126,142 ---- expandCountExpressions(); ! // molecule.debug(); ! // System.out.println("============================="); ! // add args first so every molecule has unique id ! Nodes moleculeRefs = join.query(".//cml:molecule[@ref]", X_CML); ! addArgs(moleculeRefs); // create join/@atomRefs2 join.processChildMolecules(); ! // System.out.println("-----------------???----------"); // molecule.debug(); + // System.out.println("------------!!!---------------"); + // remove all joins not join/@atomRefs2 removeNonAtomRefs2(join); *************** *** 131,142 **** flattenJoinMoleculeDescendants(molecule); molecule.setConvention(PML_INTERMEDIATE); } void expandCountExpressions() { ! // must do this recursively while (true) { Nodes nodes = ! molecule.query(".//*[local-name()='molecule' and @countExpression]"); if (nodes.size() == 0) { break; --- 146,160 ---- flattenJoinMoleculeDescendants(molecule); + // tidy join geometry + tidyJoinGeometry(molecule); + molecule.setConvention(PML_INTERMEDIATE); } void expandCountExpressions() { ! // must do this recursively (WHY??) while (true) { Nodes nodes = ! molecule.query(".//cml:molecule[@countExpression]", X_CML); if (nodes.size() == 0) { break; *************** *** 150,165 **** Node parent = molecule.getParent(); Element parentElement = (Element) parent; int idx = parentElement.indexOf(molecule); int count = molecule.calculateCount(); // detach any molecules without a reference (from hanging bond) ! Nodes nodes = molecule.query("./molecule[@ref='']"); ! System.out.println("NODES "+nodes.size()); ! molecule.debug(); if (nodes.size() == 1) { nodes.get(0).detach(); } ! // clone molecules for (int i = 1; i < count; i++) { ! CMLMolecule molecule1 = new CMLMolecule(molecule); parentElement.insertChild(molecule1, idx); --- 168,193 ---- Node parent = molecule.getParent(); Element parentElement = (Element) parent; + // position of molecule int idx = parentElement.indexOf(molecule); int count = molecule.calculateCount(); // detach any molecules without a reference (from hanging bond) ! Nodes nodes = molecule.query("cml:molecule[@ref='']", X_CML); if (nodes.size() == 1) { nodes.get(0).detach(); } ! // any child joins? if so detach and transfer to following sibling ! CMLJoin subJoin = null; ! Nodes joins = molecule.query("cml:join[not(@right) and not(@left)]", X_CML); ! if (joins.size() == 1) { ! subJoin = (CMLJoin) joins.get(0); ! subJoin.detach(); ! } ! // clone count-1 molecules and append to existing molecule for (int i = 1; i < count; i++) { ! // add join to preceeding molecule ! if (subJoin != null) { ! CMLJoin subJoin1 = new CMLJoin(subJoin); ! parentElement.insertChild(subJoin1, idx); ! } CMLMolecule molecule1 = new CMLMolecule(molecule); parentElement.insertChild(molecule1, idx); *************** *** 181,185 **** public void removeNonAtomRefs2(CMLJoin join) { Nodes nodes = ! join.query(".//*[local-name()='join' and not(@atomRefs2)]"); for (int i = 0; i < nodes.size(); i++) { CMLJoin join1 = (CMLJoin) nodes.get(i); --- 209,213 ---- public void removeNonAtomRefs2(CMLJoin join) { Nodes nodes = ! join.query(".//cml:join[not(@atomRefs2)]", X_CML); for (int i = 0; i < nodes.size(); i++) { CMLJoin join1 = (CMLJoin) nodes.get(i); *************** *** 189,207 **** } - /**- - static String getLocalRef(String s) { - int idx = s.indexOf(S_COLON); - return s.substring(idx+1); - } - - static String getPrefix(String s) { - int idx = s.indexOf(S_COLON); - return (idx == -1) ? S_EMPTY : s.substring(0, idx); - } - --*/ - private void flattenJoinMoleculeDescendants(CMLElement element) { Nodes molecules = element.query( ! ".//*[local-name()='molecule' and *[local-name()='molecule']]"); for (int i = 0; i < molecules.size(); i++) { CMLMolecule molecule = (CMLMolecule) molecules.get(i); --- 217,223 ---- } private void flattenJoinMoleculeDescendants(CMLElement element) { Nodes molecules = element.query( ! ".//cml:molecule[cml:molecule]", X_CML); for (int i = 0; i < molecules.size(); i++) { CMLMolecule molecule = (CMLMolecule) molecules.get(i); *************** *** 213,217 **** int idx = molecule.getParent().indexOf(molecule); Nodes moleculesAndJoin = ! molecule.query("*[local-name()='molecule' or local-name()='join']"); for (int i = 0; i < moleculesAndJoin.size(); i++) { Node node = moleculesAndJoin.get(i); --- 229,233 ---- int idx = molecule.getParent().indexOf(molecule); Nodes moleculesAndJoin = ! molecule.query("cml:molecule | cml:join'", X_CML); for (int i = 0; i < moleculesAndJoin.size(); i++) { Node node = moleculesAndJoin.get(i); *************** *** 220,223 **** --- 236,277 ---- } } + + // a few molecules have still not transferred their torsion and otehr contents to + // previous join + private void tidyJoinGeometry(CMLMolecule rootMolecule) { + Nodes molecules = rootMolecule.query("cml:molecule[cml:torsion | cml:length]", X_CML); + for (int i = 0; i < molecules.size(); i++) { + CMLMolecule molecule = (CMLMolecule) molecules.get(i); + Nodes torsionsAndLengths = molecule.query("cml:torsion | cml:length", X_CML); + int nnodes = torsionsAndLengths.size(); + Nodes previousSiblings = molecule.query("./preceding-sibling::*[1]"); + // is the preceding-sibling a join? + CMLJoin join = null; + if (previousSiblings.size() == 1) { + Node previousSibling = previousSiblings.get(0); + if (previousSibling instanceof CMLJoin) { + join = (CMLJoin) previousSibling; + // if not a full join or populated with geometry ignore + if (join.getAtomRefs2() == null || + join.getChildCMLElements(CMLLength.TAG).size() != 0 || + join.getChildCMLElements(CMLTorsion.TAG).size() != 0 + ) { + join = null; + } + } + } + // detach node anyway + for (int j = nnodes-1; j >= 0; j--) { + Node node = torsionsAndLengths.get(j); + node.detach(); + // attach node if join is an explicit join and does not have torsions or lengths + if (join != null) { + join.appendChild(node); + } + } + } + } + // for () + void processIntermediate() { *************** *** 263,268 **** } CMLElements<CMLJoin> joinList = molecule.getJoinElements(); for (CMLJoin join : joinList) { ! addJoinTo(join, molecule); } molecule.setConvention(PML_COMPLETE); --- 317,323 ---- } CMLElements<CMLJoin> joinList = molecule.getJoinElements(); + // this is not optimised and probably quadratic for (CMLJoin join : joinList) { ! join.joinAtomRefs2(); } molecule.setConvention(PML_COMPLETE); *************** *** 280,320 **** molecule.addBond(bond, true); } ! // copy any remaining nodes ! Nodes nodes = mol.query( ! ".//*[not(local-name()='atomArray') and not(local-name()='bondArray')]"); int nnodes = nodes.size(); for (int i = nnodes-1; i >= 0; i--) { Node node = nodes.get(i); node.detach(); ! molecule.appendChild(node); } mol.detach(); } ! void addJoinTo(CMLJoin join, CMLMolecule molecule) { ! /*-- ! String[] atomRefs2 = join.getAtomRefs2(); ! CMLAtom atom0 = molecule.getAtomById(getLocalRef(atomRefs2[0])); ! CMLAtom atom1 = molecule.getAtomById(getLocalRef(atomRefs2[1])); ! if (atom0 == null) { ! throw new CMLRuntime("Cannot find atom in bond: "+getLocalRef(atomRefs2[0])); ! } ! if (atom1 == null) { ! throw new CMLRuntime("Cannot find atom in bond: "+getLocalRef(atomRefs2[1])); ! } ! CMLBond bond = new CMLBond(atom0, atom1); ! bond.setId(atom0.getId()+S_UNDER+atom1.getId()); ! molecule.addBond(bond, true); ! // copy any remaining nodes ! Nodes nodes = join.query(".//*[local-name()='join']"); ! int nnodes = nodes.size(); ! for (int i = nnodes-1; i >= 0; i--) { ! Node node = nodes.get(i); ! node.detach(); ! molecule.appendChild(node); } - join.detach(); - --*/ - join.joinAtomRefs2(); } } --- 335,361 ---- molecule.addBond(bond, true); } ! // copy any remaining nodes except atomArray and bondArray ! Nodes nodes = mol.query(".//*", X_CML); int nnodes = nodes.size(); for (int i = nnodes-1; i >= 0; i--) { Node node = nodes.get(i); node.detach(); ! if (node instanceof CMLAtomArray) { ! } else if (node instanceof CMLBondArray) { ! } else { ! molecule.appendChild(node); ! } } mol.detach(); } ! private void processZMatrix() { ! try { ! CMLZMatrix zmat = new CMLZMatrix(molecule); ! zmat.addCartesiansTo(molecule); ! molecule.setConvention(PML_CARTESIAN); ! } catch (CMLRuntime e) { ! System.out.println(e.getMessage()); } } } Index: CrystalTool.java =================================================================== RCS file: /cvsroot/cml/jumbo53/src/org/xmlcml/cml/tools/CrystalTool.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** CrystalTool.java 23 Jun 2006 15:33:05 -0000 1.3 --- CrystalTool.java 27 Jun 2006 17:07:26 -0000 1.4 *************** *** 252,256 **** List<Contact> contactList = new ArrayList<Contact>(); if (symmetry != null && molecule != null) { ! Point3 centroidFract = molecule.calculateCentroid3(CoordinateType.FRACTIONAL); Real3Range range3Fract = molecule.calculateRange3(CoordinateType.FRACTIONAL); Real3Range range3Cart = molecule.calculateRange3(CoordinateType.CARTESIAN); --- 252,256 ---- List<Contact> contactList = new ArrayList<Contact>(); if (symmetry != null && molecule != null) { ! // Point3 centroidFract = molecule.calculateCentroid3(CoordinateType.FRACTIONAL); Real3Range range3Fract = molecule.calculateRange3(CoordinateType.FRACTIONAL); Real3Range range3Cart = molecule.calculateRange3(CoordinateType.CARTESIAN); --- NEW FILE: FragmentSequence.java --- package org.xmlcml.cml.tools; import java.util.ArrayList; import java.util.List; import nu.xom.Attribute; import nu.xom.Elements; import org.xmlcml.cml.base.CMLConstants; import org.xmlcml.cml.base.CMLRuntime; import org.xmlcml.cml.element.CMLBond; import org.xmlcml.cml.element.CMLJoin; import org.xmlcml.cml.element.CMLLength; import org.xmlcml.cml.element.CMLMolecule; import org.xmlcml.cml.element.CMLTorsion; import org.xmlcml.euclid.Util; /** * tool to support fragments building. not fully developed * * @author pmr * typical concise string (out of date) formula='f:h~r1- (r1~f:acryl [r3-(r1~f:eo~r2)range(2,5)-r1~f:et] ~r2)range(6,10) -r1:f:h * pseudo BNF for concise string (not finished) is: * concise := fragment | fragmentList * fragmentRepeat := '(' fragment ')' fragmentCount * fragmentCount := DIGIT+ | * 'range(' DIGIT+ ',' DIGIT+ ')' | * 'gaussian(' DIGIT+ ',' DIGIT+ ')' * fragment := '(' left? ref branch* right? ')' * left := '[' label ']' * label := 'r' DIGIT+ * right := '[' label ']' * branch := '[' label concise ']' * count := '*' '(' DIGIT+ | distrib ') * distrib := (gaussian DIGIT+ DIGIT+) | (range DIGIT+ DIGIT+) * * at present additional (cyclic) joins not supported */ /** class to support result of parse. * * @author pm286 * */ class FragmentSequence implements CMLConstants { List<FragmentAndBond> fragmentAndBondList = null; /** process concise string. * @param formula string */ public FragmentSequence(String formula) { fragmentAndBondList = new ArrayList<FragmentAndBond>(); if (formula == null) { throw new CMLRuntime("null concise string"); } formula = formula.trim(); while (formula.length() > 0) { if (formula.charAt(0) != Fragment.LFRAGLIST) { throw new CMLRuntime("expected '"+Fragment.LFRAGLIST+"' at: "+formula); } int idx = Util.indexOfBalancedBracket(Fragment.LFRAGLIST, formula); if (idx == -1) { throw new CMLRuntime("Unblanced '"+ Fragment.LFRAGLIST+"..."+Fragment.RFRAGLIST+"' at: "+formula); } FragmentAndBond fragmentAndBond = new FragmentAndBond(); this.addFragmentAndBond(fragmentAndBond); String fragmentS = formula.substring(1, idx); Fragment fragment = new Fragment(fragmentS); fragmentAndBond.setFragment(fragment); formula = formula.substring(fragmentS.length()+2); String countExpressionS = CountExpression.grabCountString(formula); if (formula.length() == 0) { break; } if (countExpressionS != null && !countExpressionS.equals(S_EMPTY)) { CountExpression countExpression = new CountExpression(countExpressionS); fragment.setCountExpression(countExpression); formula = formula.substring(countExpressionS.length()); } if (formula.length() == 0) { break; } String joinBondS = JoinBond.grabJoinString(formula); if (joinBondS.equals(S_EMPTY)) { throw new CMLRuntime("Expected bond at: "+formula); } JoinBond joinBond = new JoinBond(joinBondS); fragmentAndBond.setJoinBond(joinBond); formula = formula.substring(joinBondS.length()); } // System.out.println("FSEQ "+this.toString()); } /** build up fragments. * * @param fragmentAndBond */ public void addFragmentAndBond(FragmentAndBond fragmentAndBond) { fragmentAndBondList.add(fragmentAndBond); } /** gets CMLJoin from fragments. * * @return join */ public CMLJoin getCMLJoin() { CMLJoin join = new CMLJoin(); join.addAttribute( new Attribute("convention", CMLJoin.FRAGMENT_CONTAINER)); for (FragmentAndBond fragmentAndBond : fragmentAndBondList) { Fragment fragment = fragmentAndBond.getFragment(); CMLMolecule molecule = fragment.getMolecule(); Elements molecules = join.getChildCMLElements(CMLMolecule.TAG); // hanging bond inside repeatable molecules CMLMolecule previousMolecule = null; if (molecules.size() > 0) { previousMolecule = (CMLMolecule) molecules.get(molecules.size()-1); } // repeatable molecule? if (previousMolecule != null && previousMolecule.getCountExpression() != null && molecule.getRef() == null) { // associated join Elements joins = join.getChildCMLElements(CMLJoin.TAG); CMLJoin previousJoin = null; if (joins.size() > 0) { previousJoin = (CMLJoin) joins.get(joins.size()-1); } if (previousJoin != null) { previousJoin.detach(); previousMolecule.appendChild(previousJoin); } previousMolecule.appendChild(molecule); // add join from after countExpression CMLJoin subJoin = fragmentAndBond.getCMLJoin(); if (subJoin != null) { join.appendChild(subJoin); } } else { // normal concatenation join.appendChild(molecule); CMLJoin subJoin = fragmentAndBond.getCMLJoin(); if (subJoin != null) { join.appendChild(subJoin); } } } return join; } /** get list of fragments. * * @return the list */ public List<FragmentAndBond> getFragmentAndBondList() { return this.fragmentAndBondList; } /** debug string. * @return the string */ public String getString() { StringBuffer sb = new StringBuffer(); sb.append("<FS>"); for (FragmentAndBond fragmentAndBond : fragmentAndBondList) { sb.append(fragmentAndBond.getString()); } sb.append("</FS>"); return sb.toString(); } /** string. * @return the string */ public String toString() { StringBuffer sb = new StringBuffer(); for (FragmentAndBond fragmentAndBond : fragmentAndBondList) { sb.append(fragmentAndBond.toString()); } return sb.toString(); } }; class FragmentAndBond implements CMLConstants { private Fragment fragment; private JoinBond joinBond; /** constructor. */ public FragmentAndBond() { } /** set fragment at end of partial parse. * will trim brackets from fragmentList if countExpression set * @param fragment the complete fragment without trailing bond */ public void setFragment(Fragment fragment) { // System.out.println("fragment>>"+fragmentS+"<<>>"+ss+"<<"); this.fragment = fragment; } /** get fragment * * @return the fragment */ public Fragment getFragment() { return fragment; } /** set joinBond. * * @param joinBond */ public void setJoinBond(JoinBond joinBond) { this.joinBond = joinBond; } /** get join from joinBond. * * @return the join */ public CMLJoin getCMLJoin() { return (joinBond == null) ? null : joinBond.getCMLJoin(); } /** debug string. * @return the string */ public String getString() { StringBuffer sb = new StringBuffer(); sb.append("<FB>"); sb.append(fragment.getString()); sb.append("<JB>"); if (joinBond != null) { sb.append(joinBond.getString()); } sb.append("</JB>"); sb.append("</FB>"); return sb.toString(); } /** string. * @return the string */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append(fragment.toString()); if (joinBond != null) { sb.append(joinBond.toString()); } return sb.toString(); } }; class Fragment implements CMLConstants { static char LFRAGLIST = C_LBRAK; static char RFRAGLIST = C_RBRAK; static char LLABEL = C_LCURLY; static char RLABEL = C_RCURLY; private CountExpression countExpression; JoinBond repeatableBond; String fragmentS; private List<Branch> branchList; private String localRefS; private String prefixS; private String leftLabel; private String rightLabel; Branch branch; /** create fragment from string. * * @param fragmentS */ public Fragment(String fragmentS) { init(); // System.out.println("=f=>"+fragmentS+"<=f="); this.fragmentS = fragmentS; parse(fragmentS); } void init() { this.branchList = new ArrayList<Branch>(); this.countExpression = null; this.leftLabel = S_EMPTY; this.rightLabel = S_EMPTY; this.prefixS = S_EMPTY; this.localRefS = S_EMPTY; } /** set countExpression. * will trim fragmentList if necessary * @param countExpression */ public void setCountExpression(CountExpression countExpression) { this.countExpression = countExpression; } /** if fragment is repeatable, set the bond to join them. * @param repeatableBond */ public void setRepeatableBond(JoinBond repeatableBond) { this.repeatableBond = repeatableBond; } /** adds branch to branchList * @param branch to add */ public void addBranch(Branch branch) { this.branchList.add(branch); } CMLMolecule getMolecule() { CMLMolecule molecule = new CMLMolecule(); String refS = (this.prefixS.equals(S_EMPTY)) ? this.localRefS : this.prefixS+S_COLON+this.localRefS; molecule.setRef(refS); if (this.countExpression != null) { molecule.addAttribute(new Attribute("countExpression", this.countExpression.toString())); if (repeatableBond != null) { CMLJoin join = repeatableBond.getCMLJoin(); molecule.appendChild(join); } } for (Branch branch : branchList) { CMLJoin join = branch.getJoin(); molecule.appendChild(join); } CMLJoin join = new CMLJoin(); if (!this.leftLabel.equals(S_EMPTY)) { join.setLeft(this.leftLabel); } if (!this.rightLabel.equals(S_EMPTY)) { join.setRight(this.rightLabel); } if (join.getLeft() != null || join.getRight() != null) { molecule.appendChild(join); } return molecule; } /** string * of form leftLabel? namespace? ref rightLabel? OR * rightLabel * @param refS */ public void parse(String refS) { // find llabel localRefS = refS; int idx = localRefS.indexOf(LLABEL); if (idx != -1) { leftLabel = localRefS.substring(0, idx); localRefS = localRefS.substring(idx+1); } int lr = localRefS.length(); if (lr == 0) { throw new CMLRuntime("no ref given"); } idx = localRefS.indexOf(S_COLON); if (idx != -1) { prefixS = localRefS.substring(0, idx); localRefS = localRefS.substring(idx+1); } idx = getNextPunctuation(localRefS); if (idx == -1) { } else { String rightS = localRefS.substring(idx); localRefS = localRefS.substring(0, idx); // System.out.println("---->"+rightS+"<----"); while (true) { if (rightS.length() == 0) { break; } char rc = rightS.charAt(0); if (JoinBond.isBondChar(rc)) { String joinBondS = JoinBond.grabJoinString(rightS); repeatableBond = new JoinBond(joinBondS); rightS = rightS.substring(joinBondS.length()); if (!rightS.equals(S_EMPTY)) { throw new CMLRuntime("Unexpected fragment after " + "repeatableBond :"+rightS+":"); } } else if (rc == Branch.LBRANCH) { // System.out.println("XXX"+rightS); String branchS = Branch.grabBranch(rightS); // System.out.println("BBB"+branchS); Branch branch = new Branch(branchS.substring(1, branchS.length()-1)); branchList.add(branch); rightS = rightS.substring(branchS.length()); } else if (rc == RLABEL) { rightS = rightS.substring(1); rightLabel = rightS; idx = getNextPunctuation(rightS); if (idx != -1) { if (JoinBond.isBondChar(rightS.charAt(idx))) { rightS = rightS.substring(idx); rightLabel = rightLabel.substring(0, idx); } else { throw new CMLRuntime("Unexpected fragment after right label: "+rightS.substring(idx)); } } else { // ends with rlabel break; } } else { throw new CMLRuntime("Unexpected fragment in parse: "+rightS); } } } } private int getNextPunctuation(String s) { int idx = -1; int l = s.length(); for (int i = 0; i < l; i++) { char c = s.charAt(i); if (JoinBond.isBondChar(c) || c == Branch.LBRANCH || c == RLABEL ) { idx = i; break; } } return idx; } /** debug string. * @return string */ public String getString() { StringBuffer sb = new StringBuffer(); // sb.append("<fs>"); // sb.append(fragmentS); // sb.append("</fs>"); sb.append("<F>"); sb.append("<ll>"); if (!leftLabel.equals(S_EMPTY)) { sb.append(leftLabel); } sb.append("</ll>"); sb.append("<p>"); if (!prefixS.equals(S_EMPTY)) { sb.append(prefixS); sb.append(S_COLON); } sb.append("</p>"); sb.append("<lr>"); sb.append(localRefS); sb.append("</lr>"); for (Branch branch : branchList) { sb.append(branch.getString()); } sb.append("<r>"); if (!rightLabel.equals(S_EMPTY)) { sb.append(rightLabel); } sb.append("</r>"); sb.append("<rb>"); if (repeatableBond != null) { sb.append(repeatableBond.getString()); } sb.append("</rb>"); sb.append("<ce>"); if (countExpression != null) { sb.append(countExpression.getString()); } sb.append("</ce>"); sb.append("</F>"); String s = sb.toString(); return s; } /** string. * @return string */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append(LFRAGLIST); if (!leftLabel.equals(S_EMPTY)) { sb.append(leftLabel); sb.append(LLABEL); } if (!prefixS.equals(S_EMPTY)) { sb.append(prefixS); sb.append(S_COLON); } sb.append(localRefS); for (Branch branch : branchList) { sb.append(branch.toString()); } if (!rightLabel.equals(S_EMPTY)) { sb.append(RLABEL); sb.append(rightLabel); } if (repeatableBond != null) { sb.append(repeatableBond); } sb.append(RFRAGLIST); if (countExpression != null) { sb.append(countExpression); } String s = sb.toString(); return s; } }; class JoinBond implements CMLConstants { static char LBOND = C_LSQUARE; static char RBOND = C_RSQUARE; /** single bond symbol. */ public final static char SINGLEBOND = C_MINUS; /** double bond symbol. */ public final static char DOUBLEBOND = C_EQUALS; /** triple bond symbol. */ public final static char TRIPLEBOND = C_HASH; CMLLength length = null; CMLTorsion torsion = null; String torsionS = null; // original value (for parsing) String lengthS = null; String order = CMLBond.SINGLE; String joinBondS = null; /** length keyword. */ public final static String LEN = "l"; /** torsion keyword. */ public final static String TOR = "t"; /** constructor. * * @param jBondS */ public JoinBond(String jBondS) { if (jBondS == null || jBondS.trim().length() == 0) { throw new CMLRuntime("empty bond type"); } // System.out.println("~~~~~~~~~~~~~"+jBondS); this.joinBondS = jBondS; char c = jBondS.charAt(0); if (c == SINGLEBOND) { order = CMLBond.SINGLE; } else if (c == DOUBLEBOND) { order = CMLBond.DOUBLE; } else if (c == TRIPLEBOND) { order = CMLBond.TRIPLE; } else { throw new CMLRuntime("Bad bond type: "+c); } // System.out.println("~~~~~~~~~~~~~"+order+"/"+c); jBondS = jBondS.substring(1); processQualifiers(jBondS); } static String grabJoinString(String fff) { String ff = fff; String s = S_EMPTY; if (ff.length() > 0) { if (!JoinBond.isBondChar(ff.charAt(0))) { throw new CMLRuntime("expected bond type at: "+ff+" in "+fff); } String f = ff.substring(1); // bond type s = ff.substring(0, 1); // bond type and qualifiers if (f.length() > 0 && f.charAt(0) == JoinBond.LBOND) { int rbr = Util.indexOfBalancedBracket(JoinBond.LBOND, f); if (rbr == -1) { throw new CMLRuntime( "Unbalanced: "+JoinBond.LBOND+"..."+JoinBond.RBOND); } s += f.substring(0, rbr+1); // System.out.println(">>>>"+s+"<<"); } else { s = ff.substring(0, 1); // System.out.println(">>"+s+"<<<<"); } } return s; } /** current syntax. * len(1.4),tor(...) * tor is tor(120) or tor(evaluate(...)) * @param jBondS */ void processQualifiers(String jBondS) { // System.out.println(("@"+jBondS+"@")); if (jBondS.equals(S_EMPTY)) { } else if (jBondS.charAt(0) == LBOND) { int idx = Util.indexOfBalancedBracket(LBOND, jBondS); if (idx == -1) { throw new CMLRuntime("Unbalanced "+LBOND+"..."+RBOND); } jBondS = jBondS.substring(1, jBondS.length()-1); if (jBondS.equals(S_EMPTY)) { throw new CMLRuntime("bond qualifier should not be empty"); } lengthS = null; torsionS = null; while(jBondS.length() > 0) { if (jBondS.startsWith(LEN+C_LBRAK)) { lengthS = grabKeywordBrackets(LEN, jBondS); processLength(lengthS); jBondS = jBondS.substring(LEN.length()+lengthS.length()+2); } else if (jBondS.startsWith(TOR+C_LBRAK)) { torsionS = grabKeywordBrackets(TOR, jBondS); processTorsion(torsionS); jBondS = jBondS.substring(TOR.length()+torsionS.length()+2); } else if (jBondS.charAt(0) == C_COMMA) { jBondS = jBondS.substring(1); } else { throw new CMLRuntime("must give keyworded qualifiers"); } } } } String grabKeywordBrackets(String keyword, String s) { s = s.substring(keyword.length()); int idx = Util.indexOfBalancedBracket(C_LBRAK, s); if (idx == -1) { throw new CMLRuntime("Cannot find balanced bracket in: "+s); } return s.substring(1, idx); } String grabNumber(String s) { int idx = s.indexOf(S_COMMA); if (idx != -1) { s = s.substring(0, idx); } try { new Double(s); } catch (NumberFormatException e) { s = null; } return s; } void processLength(String s) { try { Double lengthD = new Double(s); if (lengthD != null) { length = new CMLLength(); length.setXMLContent(lengthD.doubleValue()); } } catch (NumberFormatException e) { throw new CMLRuntime("Cannot interpret as length: "+e); } } void processTorsion(String s) { try { Double torsionD = new Double(s); if (torsionD != null) { torsion = new CMLTorsion(); torsion.setXMLContent(torsionD.doubleValue()); } } catch (NumberFormatException e) { throw new CMLRuntime("Cannot interpret as torsion: "+e); } } CMLJoin getCMLJoin() { CMLJoin subJoin = new CMLJoin(); CMLTorsion torsion = this.getTorsion(); if (torsion != null) { torsion.detach(); subJoin.appendChild(torsion); } CMLLength length = this.getLength(); if (length != null) { length.detach(); subJoin.appendChild(length); } if (this.order != null) { subJoin.setOrder(this.order); } return subJoin; } CMLLength getLength() { return length; } CMLTorsion getTorsion() { return torsion; } /** get debug string. * * @return the string */ public String getString() { StringBuffer sb = new StringBuffer(); sb.append("<B>"); sb.append("<o>"); sb.append(getOrderSymbol(order)); sb.append("</o>"); sb.append("<q>"); sb.append("<l>"); if (length != null) { sb.append(lengthS); } sb.append("</l>"); sb.append("<t>"); if (torsion != null) { sb.append(torsionS); } sb.append("</t>"); sb.append("</q>"); sb.append("</B>"); return sb.toString(); } /** get original string. * * @return the string */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append(getOrderSymbol(order)); if (length != null || torsion != null) { sb.append(LBOND); if (length != null) { sb.append(LEN); sb.append(C_LBRAK); sb.append(lengthS); sb.append(C_RBRAK); } if (torsion != null) { sb.append(TOR); sb.append(C_LBRAK); sb.append(torsionS); sb.append(C_RBRAK); } sb.append(RBOND); } return sb.toString(); } /** translate CMLBond order into symbols. * * @param orderS CMLBond.SINGLE, etc. * @return S_MINUS, S_EQUALS, etc. */ public static String getOrderSymbol(String orderS) { String orderSymbol = S_MINUS; if (orderS == null || orderS.equals(CMLBond.SINGLE)) { } else if (orderS.equals(CMLBond.DOUBLE)) { orderSymbol = S_EQUALS; } else if (orderS.equals(CMLBond.TRIPLE)) { orderSymbol = S_HASH; } return orderSymbol; } /** does this character define a bond. * * @param c character * @return tru id SINGLE/DOUBLE/TRIPLE */ public static boolean isBondChar(char c) { boolean isChar = c == SINGLEBOND || c == DOUBLEBOND || c == TRIPLEBOND; return isChar; } } class Branch implements CMLConstants { static char LBRANCH = C_LSQUARE; static char RBRANCH = C_RSQUARE; String leftLabel; JoinBond joinBond; FragmentSequence fragmentSequence = null; CMLJoin join; String branchS = S_EMPTY; /** parse string to create branch. * * @param brs full branch string */ public Branch(String brs) { // System.out.println("=b=>"+brs+"<=b="); this.branchS = brs; leftLabel = grabParentLink(branchS); branchS = branchS.substring(leftLabel.length()); // System.out.println("BRANCHS: "+branchS); // String joinString = FragmentAndBond.grabJoinString(branchS, allowHangingBond); String joinString = JoinBond.grabJoinString(branchS); // System.out.println("BRANCHJOIN: "+joinString); joinBond = new JoinBond(joinString); // System.out.println("JOINBOND>>>"+joinBond.toString()+"<<"); branchS = branchS.substring(joinString.length()); // System.out.println("BRANCHS: "+branchS); // fragmentSequence = FragmentAndBond.processConcise1(branchS); fragmentSequence = new FragmentSequence(branchS); join = fragmentSequence.getCMLJoin(); join.setLinkOnParent(leftLabel); CMLJoin subJoin = this.getSubJoin(); join.insertChild(subJoin, 0); join.setConvention("branch"); } static String grabBranch(String s) { if (s != null && s.length() > 0 && s.charAt(0) == LBRANCH) { int idx = Util.indexOfBalancedBracket(LBRANCH, s); s = s.substring(0, idx+1); } return s; } private String grabParentLink(String s) { int idx = 0; while (true) { if (idx >= s.length()) { throw new CMLRuntime("expect bond after parentLInk in branch"); } if (JoinBond.isBondChar(s.charAt(idx))) { break; } idx++; } return s.substring(0, idx); } /** return new join element and add convert fragment children to molecules. * * @return the join */ public CMLJoin getJoin() { return join; } private CMLJoin getSubJoin() { CMLJoin subJoin = new CMLJoin(); subJoin.setOrder(joinBond.order); CMLLength length = joinBond.getLength(); if (length != null) { length.detach(); subJoin.appendChild(length); } CMLTorsion torsion = joinBond.getTorsion(); if (torsion != null) { torsion.detach(); subJoin.appendChild(torsion); } return subJoin; } /** debug string. * @return value */ public String getString() { StringBuffer sb = new StringBuffer(); sb.append("<Br>"); sb.append("<ll>"); sb.append(leftLabel); sb.append("</ll>"); sb.append("<jb>"); sb.append(joinBond.getString()); sb.append("</jb>"); sb.append(fragmentSequence.getString()); sb.append("</Br>"); return sb.toString(); } /** to string. * @return value */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append(LBRANCH); sb.append(leftLabel); sb.append(Fragment.RLABEL); sb.append(joinBond.getString()); sb.append(fragmentSequence.getString()); sb.append(RBRANCH); return sb.toString(); } }; class CountExpression implements CMLConstants { /** left bracket for count. */ static char LCOUNTBRAK = C_LBRAK; /** right bracket for count. */ static char RCOUNTBRAK = C_RBRAK; /** range. */ public static String RANGE = "range"; /** gaussian. */ public static String GAUSSIAN = "gaussian"; String countExpressionS; /** constructor. * * @param s raw string */ public CountExpression(String s) { countExpressionS = s; } /** return raw string. * * @return raw string */ public String getString() { StringBuffer sb = new StringBuffer(); sb.append("<CE>"); sb.append(countExpressionS); sb.append("</CE>"); return sb.toString(); } /** grabs countExpression if it exists. * * @param formula * @return empty string if none */ public static String grabCountString(String formula) { String s = S_EMPTY; int ll = 0; if (formula.length() == 0) { } else if (formula.startsWith(S_STAR+LCOUNTBRAK)) { ll = 1; } else if (formula.startsWith(RANGE+LCOUNTBRAK)) { ll = RANGE.length(); } else if (formula.startsWith(GAUSSIAN+LCOUNTBRAK)) { ll = GAUSSIAN.length(); } else { } if (ll != 0) { int rbr = Util.indexOfBalancedBracket(LCOUNTBRAK, formula.substring(ll)); if (rbr == -1) { throw new CMLRuntime("Cannot find balanced bracket:"+formula); } s = formula.substring(0, rbr+ll+1); } return s; } /** to string. * @return value */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append(countExpressionS); return sb.toString(); } }; |