/** * Utility to generate a bond expression. * <pre>{@code * Expr expr = new Expr(Expr.Type.TRUE); * String bExpr = Smarts.generateBond(expr); * // bExpr='~' * }</pre> * @see Expr * @param expr the expression * @return the SMARTS atom expression */ public static String generateBond(Expr expr) { // default bond type if (expr.type() == SINGLE_OR_AROMATIC) return ""; StringBuilder sb = new StringBuilder(); generateBond(sb, expr); return sb.toString(); }
private static boolean hasOr(Expr expr) { for (; ; ) { switch (expr.type()) { case AND: if (hasOr(expr.left())) return true; expr = expr.right(); break; case OR: return expr.left().type() != STEREOCHEMISTRY || expr.right().type() != STEREOCHEMISTRY || expr.right().value() != 0; case SINGLE_OR_AROMATIC: case SINGLE_OR_DOUBLE: case DOUBLE_OR_AROMATIC: return true; default: return false; } } }
switch (expr.type()) { case AND: case OR: Expr right = strip(expr.right(), type); if (left != null && right != null) expr.setLogical(expr.type(), left, right); else if (left != null) return left; Expr sub = strip(expr.left(), type); if (sub != null) { expr.setLogical(expr.type(), sub, null); return expr; } else { return expr.type() == type ? null : expr;
String generateAtom(IAtom atom, Expr expr) { if (expr.type() == AND) { if (expr.left().type() == Expr.Type.REACTION_ROLE) return generateAtom(atom, expr.right()); if (expr.right().type() == Expr.Type.REACTION_ROLE) return generateAtom(atom, expr.left()); switch (expr.type()) { case TRUE: return "*";
/** * Traverse an expression tree and flip all the stereo expressions. */ void flip(Expr expr) { for (; ; ) { switch (expr.type()) { case STEREOCHEMISTRY: if (expr.value() != 0) expr.setPrimitive(expr.type(), expr.value() ^ 0x3); return; case AND: case OR: flip(expr.left()); expr = expr.right(); break; case NOT: expr = expr.left(); break; } } }
@Test public void singleOrDoubleBond() throws Exception { String input = " 1 3 5 0 0 0 0"; IBond bond = reader.readBondFast(input, builder, atoms, new int[atoms.length], 1); assertThat(bond.getStereo(), is(IBond.Stereo.NONE)); assertFalse(bond.getFlag(CDKConstants.ISAROMATIC)); assertFalse(bond.getFlag(CDKConstants.SINGLE_OR_DOUBLE)); assertThat(bond, is(instanceOf(QueryBond.class))); assertThat(((QueryBond) bond).getExpression().type(), is(Expr.Type.SINGLE_OR_DOUBLE)); }
boolean hasAliphaticDoubleBond(Expr expr) { for (; ; ) { switch (expr.type()) { case NOT: expr = expr.left(); break; case AND: case OR: if (hasAliphaticDoubleBond(expr.left())) return true; expr = expr.right(); break; case ALIPHATIC_ORDER: return expr.value() == 2; default: return false; } } }
@Test public void singleOrAromaticBond() throws Exception { String input = " 1 3 6 0 0 0 0"; IBond bond = reader.readBondFast(input, builder, atoms, new int[atoms.length], 1); assertThat(bond.getStereo(), is(IBond.Stereo.NONE)); assertFalse(bond.getFlag(CDKConstants.ISAROMATIC)); assertFalse(bond.getFlag(CDKConstants.SINGLE_OR_DOUBLE)); assertThat(bond, is(instanceOf(QueryBond.class))); assertThat(((QueryBond) bond).getExpression().type(), is(Expr.Type.SINGLE_OR_AROMATIC)); }
@Test public void doubleOrAromaticBond() throws Exception { String input = " 1 3 7 0 0 0 0"; IBond bond = reader.readBondFast(input, builder, atoms, new int[atoms.length], 1); assertThat(bond.getStereo(), is(IBond.Stereo.NONE)); assertFalse(bond.getFlag(CDKConstants.ISAROMATIC)); assertFalse(bond.getFlag(CDKConstants.SINGLE_OR_DOUBLE)); assertThat(bond, is(instanceOf(QueryBond.class))); assertThat(((QueryBond) bond).getExpression().type(), is(Expr.Type.DOUBLE_OR_AROMATIC)); }
@Test public void anyBond() throws Exception { String input = " 1 3 8 0 0 0 0"; IBond bond = reader.readBondFast(input, builder, atoms, new int[atoms.length], 1); assertThat(bond.getStereo(), is(IBond.Stereo.NONE)); assertFalse(bond.getFlag(CDKConstants.ISAROMATIC)); assertFalse(bond.getFlag(CDKConstants.SINGLE_OR_DOUBLE)); assertThat(bond, is(instanceOf(QueryBond.class))); assertThat(((QueryBond) bond).getExpression().type(), is(Expr.Type.TRUE)); }
@Test public void testLeftBalancedAnd2() { Expr expr1 = new Expr(ELEMENT, 9); Expr expr2 = new Expr(DEGREE, 2).and(new Expr(HAS_IMPLICIT_HYDROGEN)); expr2.and(expr1); assertThat(expr2.left().type(), is(DEGREE)); assertThat(expr2.right().type(), is(AND)); assertThat(expr2.right().left().type(), is(HAS_IMPLICIT_HYDROGEN)); assertThat(expr2.right().right().type(), is(ELEMENT)); }
private boolean parseRange(Expr expr) { if (next() != '{') return false; int lo = nextUnsignedInt(); if (next() != '-') return false; int hi = nextUnsignedInt(); Expr.Type type = expr.type(); // adjusted types switch (type) { case HAS_IMPLICIT_HYDROGEN: type = IMPL_H_COUNT; break; } expr.setPrimitive(type, lo); for (int i = lo + 1; i <= hi; i++) expr.or(new Expr(type, i)); return next() == '}'; }
@Test public void testLeftBalancedOr1() { Expr expr1 = new Expr(ELEMENT, 9); Expr expr2 = new Expr(ELEMENT, 17).or(new Expr(ELEMENT, 35)); expr1.or(expr2); assertThat(expr1.left().type(), is(ELEMENT)); }
private static int getBondStereoFlag(Expr expr) { switch (expr.type()) { case STEREOCHEMISTRY: switch (expr.value()) { case 0: return BSTEREO_UNSPEC; case IStereoElement.TOGETHER: return BSTEREO_CIS; case IStereoElement.OPPOSITE: return BSTEREO_TRANS; default: throw new IllegalArgumentException(); } case OR: return getBondStereoFlag(expr.left()) | getBondStereoFlag(expr.right()); case AND: return getBondStereoFlag(expr.left()) & getBondStereoFlag(expr.right()); case NOT: return ~getBondStereoFlag(expr.left()); default: return BSTEREO_ANY; } }
break; case '&': if (dest.type() == Expr.Type.NONE) return false; expr = new Expr(Expr.Type.NONE); break; case ';': if (dest.type() == Expr.Type.NONE) return false; if (hasPrecedence(lastOp, ';')) break; case ',': if (dest.type() == Expr.Type.NONE) return false; if (hasPrecedence(lastOp, ',')) default: pos--; return dest.type() != Expr.Type.NONE; if (dest.type() == Expr.Type.NONE) { dest.set(expr);
switch (left.type()) { case AND: case OR: Expr sub2 = determineBondStereo(left.right(), right); if (sub1 != null && sub2 != null) return new Expr(left.type(), sub1, sub2); else if (sub1 != null) return sub1; break; case STEREOCHEMISTRY: switch (right.type()) { case AND: case OR: sub2 = determineBondStereo(left, right.right()); if (sub1 != null && sub2 != null) return new Expr(right.type(), sub1, sub2); else if (sub1 != null) return sub1;
@Test public void testLeftBalancedOr2() { Expr expr1 = new Expr(ELEMENT, 9); Expr expr2 = new Expr(ELEMENT, 17).or(new Expr(ELEMENT, 35)); expr2.or(expr1); assertThat(expr2.left().type(), is(ELEMENT)); }
/** * Tests a molfile with 'query' bond types (in this case bond type == 6). */ @Test public void testQueryBondType6() throws Exception { String filename = "data/mdl/chebi.querybond.51736.mol"; InputStream ins = this.getClass().getClassLoader().getResourceAsStream(filename); MDLV2000Reader reader = new MDLV2000Reader(ins); IAtomContainer atc = reader.read(new AtomContainer()); reader.close(); int queryBondCount = 0; for (IBond bond : atc.bonds()) { if (bond instanceof QueryBond) { queryBondCount++; assertSame(((QueryBond) bond).getExpression().type(), Expr.Type.SINGLE_OR_AROMATIC); } } Assert.assertEquals("Expecting six 'query' bond types", 6, queryBondCount); }
@Test public void testLeftBalancedAnd1() { Expr expr1 = new Expr(ELEMENT, 9); Expr expr2 = new Expr(DEGREE, 2).and(new Expr(HAS_IMPLICIT_HYDROGEN)); expr1.and(expr2); assertThat(expr1.left().type(), is(ELEMENT)); }
/** * Tests a molfile with 'query' bond types (in this case bond type == 8 (any)). */ @Test public void testQueryBondType8() throws Exception { String filename = "data/mdl/iridiumCoordination.chebi52748.mol"; InputStream ins = this.getClass().getClassLoader().getResourceAsStream(filename); MDLV2000Reader reader = new MDLV2000Reader(ins); IAtomContainer atc = reader.read(new AtomContainer()); reader.close(); int queryBondCount = 0; for (IAtom atom : atc.atoms()) { if (atom.getSymbol().equals("Ir")) { for (IBond bond : atc.getConnectedBondsList(atom)) { if (bond instanceof QueryBond) { queryBondCount++; assertSame(((QueryBond) bond).getExpression().type(), Expr.Type.TRUE); } } } } Assert.assertEquals("Expecting three 'query' bond types to 'Ir'", 3, queryBondCount); }