Skip to content

Commit ae25719

Browse files
committed
Some support for reading M ALS (atom list) queries from V2000.
1 parent 9e1357e commit ae25719

File tree

4 files changed

+128
-3
lines changed

4 files changed

+128
-3
lines changed

storage/ctab/src/main/java/org/openscience/cdk/io/MDLV2000Reader.java

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
package org.openscience.cdk.io;
2626

2727
import com.google.common.collect.ImmutableSet;
28+
import org.openscience.cdk.AtomRef;
2829
import org.openscience.cdk.CDKConstants;
2930
import org.openscience.cdk.config.Elements;
3031
import org.openscience.cdk.config.IsotopeFactory;
@@ -48,6 +49,10 @@
4849
import org.openscience.cdk.io.setting.BooleanIOSetting;
4950
import org.openscience.cdk.io.setting.IOSetting;
5051
import org.openscience.cdk.isomorphism.matchers.Expr;
52+
import org.openscience.cdk.isomorphism.matchers.IQueryAtom;
53+
import org.openscience.cdk.isomorphism.matchers.IQueryAtomContainer;
54+
import org.openscience.cdk.isomorphism.matchers.IQueryBond;
55+
import org.openscience.cdk.isomorphism.matchers.QueryAtom;
5156
import org.openscience.cdk.isomorphism.matchers.QueryAtomContainer;
5257
import org.openscience.cdk.isomorphism.matchers.QueryBond;
5358
import org.openscience.cdk.sgroup.Sgroup;
@@ -430,8 +435,10 @@ private IAtomContainer readAtomContainer(IAtomContainer molecule) throws CDKExce
430435
linecount++;
431436

432437
bonds[i] = readBondFast(line, molecule.getBuilder(), atoms, explicitValence, linecount);
433-
hasQueryBonds = hasQueryBonds
434-
|| (bonds[i].getOrder() == IBond.Order.UNSET && !bonds[i].getFlag(CDKConstants.ISAROMATIC));
438+
hasQueryBonds = hasQueryBonds ||
439+
bonds[i] instanceof IQueryBond ||
440+
(bonds[i].getOrder() == IBond.Order.UNSET &&
441+
!bonds[i].getFlag(CDKConstants.ISAROMATIC));
435442
}
436443

437444
if (!hasQueryBonds)
@@ -517,7 +524,7 @@ private IAtomContainer readAtomContainer(IAtomContainer molecule) throws CDKExce
517524
// sanity check that we have a decent molecule, query bonds mean we
518525
// don't have a hydrogen count for atoms and stereo perception isn't
519526
// currently possible
520-
if (!hasQueryBonds && addStereoElements.isSet() && hasX && hasY) {
527+
if (!(outputContainer instanceof IQueryAtomContainer) && addStereoElements.isSet() && hasX && hasY) {
521528
if (hasZ) { // has 3D coordinates
522529
outputContainer.setStereoElements(StereoElementFactory.using3DCoordinates(outputContainer)
523530
.createAll());
@@ -896,6 +903,47 @@ void readPropertiesFast(final BufferedReader input, final IAtomContainer contain
896903
if (group == null) return;
897904
break;
898905

906+
// M ALS aaannn e 11112222 ...
907+
// 012345678901234567
908+
// aaa: atom index
909+
// nnn: count
910+
// e: T/F(default) exclusion list
911+
// 1111: symbol
912+
case M_ALS:
913+
index = readUInt(line, 7, 3)-1;
914+
// count = readUInt(line, 10, 3); // not needed
915+
{
916+
boolean negate = line.charAt(13) == 'T' ||
917+
line.charAt(14) == 'T';
918+
Expr expr = new Expr(Expr.Type.TRUE);
919+
StringBuilder sb = new StringBuilder();
920+
for (int i = 16; i < line.length(); i++) {
921+
if (line.charAt(i) != ' ') {
922+
sb.append(line.charAt(i));
923+
} else if (sb.length() != 0) {
924+
int elem = Elements.ofString(sb.toString()).number();
925+
if (elem != 0)
926+
expr.or(new Expr(Expr.Type.ELEMENT, elem));
927+
sb.setLength(0);
928+
}
929+
}
930+
if (sb.length() != 0) {
931+
int elem = Elements.ofString(sb.toString()).number();
932+
if (elem != 0)
933+
expr.or(new Expr(Expr.Type.ELEMENT, elem));
934+
}
935+
if (negate)
936+
expr.negate();
937+
IAtom atom = container.getAtom(index);
938+
if (AtomRef.deref(atom) instanceof QueryAtom) {
939+
QueryAtom ref = (QueryAtom)AtomRef.deref(atom);
940+
ref.setExpression(expr);
941+
} else {
942+
container.setAtom(index, new QueryAtom(expr));
943+
}
944+
}
945+
break;
946+
899947
// M CHGnn8 aaa vvv ...
900948
//
901949
// vvv: -15 to +15. Default of 0 = uncharged atom. When present, this property supersedes

storage/ctab/src/test/java/org/openscience/cdk/io/MDLV2000ReaderTest.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.junit.BeforeClass;
3030
import org.junit.Test;
3131
import org.openscience.cdk.AtomContainer;
32+
import org.openscience.cdk.AtomRef;
3233
import org.openscience.cdk.CDKConstants;
3334
import org.openscience.cdk.ChemFile;
3435
import org.openscience.cdk.ChemModel;
@@ -49,6 +50,9 @@
4950
import org.openscience.cdk.io.IChemObjectReader.Mode;
5051
import org.openscience.cdk.io.listener.PropertiesListener;
5152
import org.openscience.cdk.isomorphism.matchers.Expr;
53+
import org.openscience.cdk.isomorphism.matchers.IQueryAtomContainer;
54+
import org.openscience.cdk.isomorphism.matchers.QueryAtom;
55+
import org.openscience.cdk.isomorphism.matchers.QueryAtomContainer;
5256
import org.openscience.cdk.isomorphism.matchers.QueryBond;
5357
import org.openscience.cdk.sgroup.Sgroup;
5458
import org.openscience.cdk.sgroup.SgroupBracket;
@@ -1826,4 +1830,35 @@ public void testBadAtomCoordinateFormat() throws Exception {
18261830
is("Blah"));
18271831
}
18281832
}
1833+
1834+
@Test public void atomList() throws Exception {
1835+
try (InputStream in = getClass().getResourceAsStream("query_atomlist.mol");
1836+
MDLV2000Reader mdlr = new MDLV2000Reader(in)) {
1837+
IQueryAtomContainer mol = mdlr.read(new QueryAtomContainer(SilentChemObjectBuilder.getInstance()));
1838+
IAtom deref = AtomRef.deref(mol.getAtom(0));
1839+
assertThat(deref, CoreMatchers.<IAtom>instanceOf(QueryAtom.class));
1840+
QueryAtom queryAtom = (QueryAtom) deref;
1841+
Expr expr = queryAtom.getExpression();
1842+
Expr expected = new Expr(Expr.Type.ELEMENT, 9) // F
1843+
.or(new Expr(Expr.Type.ELEMENT, 7)) // N
1844+
.or(new Expr(Expr.Type.ELEMENT, 8)); // O
1845+
assertThat(expr, is(expected));
1846+
}
1847+
}
1848+
1849+
@Test public void notatomList() throws Exception {
1850+
try (InputStream in = getClass().getResourceAsStream("query_notatomlist.mol");
1851+
MDLV2000Reader mdlr = new MDLV2000Reader(in)) {
1852+
IQueryAtomContainer mol = mdlr.read(new QueryAtomContainer(SilentChemObjectBuilder.getInstance()));
1853+
IAtom deref = AtomRef.deref(mol.getAtom(0));
1854+
assertThat(deref, CoreMatchers.<IAtom>instanceOf(QueryAtom.class));
1855+
QueryAtom queryAtom = (QueryAtom) deref;
1856+
Expr expr = queryAtom.getExpression();
1857+
Expr expected = new Expr(Expr.Type.ELEMENT, 9) // F
1858+
.or(new Expr(Expr.Type.ELEMENT, 7)) // N
1859+
.or(new Expr(Expr.Type.ELEMENT, 8)); // O
1860+
expected = expected.negate();
1861+
assertThat(expr, is(expected));
1862+
}
1863+
}
18291864
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
2+
Mrv1810 05242013152D
3+
4+
7 7 1 0 0 0 999 V2000
5+
0.7145 2.0625 0.0000 L 0 0 0 0 0 0 0 0 0 0 0 0
6+
0.7145 1.2375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
7+
1.4289 0.8250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
8+
1.4289 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
9+
0.7145 -0.4125 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
10+
0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
11+
0.0000 0.8250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
12+
1 2 1 0 0 0 0
13+
2 3 1 0 0 0 0
14+
3 4 1 0 0 0 0
15+
4 5 1 0 0 0 0
16+
5 6 1 0 0 0 0
17+
6 7 1 0 0 0 0
18+
2 7 1 0 0 0 0
19+
1 F 3 9 7 8
20+
M ALS 1 3 F N O
21+
M END
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
2+
Mrv1810 05242013152D
3+
4+
7 7 1 0 0 0 999 V2000
5+
0.7145 2.0625 0.0000 L 0 0 0 0 0 0 0 0 0 0 0 0
6+
0.7145 1.2375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
7+
1.4289 0.8250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
8+
1.4289 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
9+
0.7145 -0.4125 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
10+
0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
11+
0.0000 0.8250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
12+
1 2 1 0 0 0 0
13+
2 3 1 0 0 0 0
14+
3 4 1 0 0 0 0
15+
4 5 1 0 0 0 0
16+
5 6 1 0 0 0 0
17+
6 7 1 0 0 0 0
18+
2 7 1 0 0 0 0
19+
1 F 3 9 7 8
20+
M ALS 1 3 T F N O
21+
M END

0 commit comments

Comments
 (0)