Skip to content

Commit 149ba57

Browse files
committed
Passing basic Data Sgroup info.
1 parent b837f0a commit 149ba57

File tree

5 files changed

+145
-10
lines changed

5 files changed

+145
-10
lines changed

base/core/src/main/java/org/openscience/cdk/sgroup/SgroupKey.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,12 @@ public enum SgroupKey {
4444
CtabBracket,
4545
CtabBracketStyle,
4646
CtabClass,
47-
CtabParentAtomList, CtabComponentNumber;
47+
CtabParentAtomList,
48+
CtabComponentNumber,
49+
// Data Sgroups
50+
DataFieldName,
51+
DataFieldFormat,
52+
DataFieldUnits,
53+
DataDisplayInformation,
54+
Data;
4855
}

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

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,70 @@ void readPropertiesFast(final BufferedReader input, final IAtomContainer contain
12941294
}
12951295
break;
12961296

1297+
// Data Sgroup Field Description
1298+
// M SDT sss ffffffffffffffffffffffffffffffgghhhhhhhhhhhhhhhhhhhhiijjj...
1299+
// 0123456789012345678901234567890123456789012345678901234567890123456789
1300+
// 1 2 3 4 5 6
1301+
// 7 sss: Index of data Sgroup
1302+
// 11 fff...fff: 30 character field name - no blanks, commas, or hyphens for MACCS-II
1303+
// 41 gg: Field type - F=formatted, N=numberic, T=text (ignored)
1304+
// 43 hhh...hhh: 20-character field units or format
1305+
// 63 ii: Nonblank if data line is a query rather than Sgroup data, MQ= MACCS-II query,
1306+
// IQ= ISIS query, PQ = program name code query
1307+
// 65 jjj...: Data query operator
1308+
case M_SDT:
1309+
sgroup = ensureSgroup(sgroups, readMolfileInt(line, 7));
1310+
if (length < 11)
1311+
break;
1312+
String name = line.substring(11, Math.min(41, length))
1313+
.trim();
1314+
sgroup.putValue(SgroupKey.DataFieldName, name);
1315+
if (length < 41)
1316+
break;
1317+
String fmt = line.substring(41, Math.min(43, length))
1318+
.trim();
1319+
if (fmt.length() == 1 &&
1320+
fmt.charAt(0) != 'F' && fmt.charAt(0) != 'N' &&
1321+
fmt.charAt(0) != 'T')
1322+
handleError("Invalid Data Sgroup field format: " + fmt);
1323+
if (!fmt.isEmpty())
1324+
sgroup.putValue(SgroupKey.DataFieldFormat, fmt);
1325+
if (length < 43)
1326+
break;
1327+
String units = line.substring(43, Math.min(63, length))
1328+
.trim();
1329+
if (!units.isEmpty())
1330+
sgroup.putValue(SgroupKey.DataFieldUnits, units);
1331+
// We don't handle data group queries
1332+
break;
1333+
1334+
// Data Sgroup Display Info
1335+
case M_SDD:
1336+
// TODO
1337+
break;
1338+
1339+
// Data Sgroup Data
1340+
// M SCD sss d...
1341+
// M SED sss d...
1342+
// 0123456789012345...
1343+
// 1
1344+
//
1345+
// d...: Line of data for data Sgroup sss (69 chars per line, columns 12-80)
1346+
//
1347+
// SCD where C = Continue, SED where E = End
1348+
// Formally multi-line data should have one or more SCD's and
1349+
// end with an SED. Single line data just has a single SED
1350+
case M_SCD:
1351+
case M_SED:
1352+
// we could be more strict and raise an error if we see an
1353+
// SCD after SED...
1354+
sgroup = ensureSgroup(sgroups, readMolfileInt(line, 7));
1355+
String data = line.substring(11, Math.min(79,length));
1356+
String curr = sgroup.getValue(SgroupKey.Data);
1357+
if (curr != null) data = curr + data;
1358+
sgroup.putValue(SgroupKey.Data, data);
1359+
break;
1360+
12971361
// M END
12981362
//
12991363
// This entry goes at the end of the properties block and is required for molfiles which contain a
@@ -2305,10 +2369,10 @@ enum PropertyKey {
23052369
/** Data Sgroup Display Information [Sgroup]. */
23062370
M_SDD,
23072371

2308-
/** Data Sgroup Data. */
2372+
/** Data Sgroup Data Continue. */
23092373
M_SCD,
23102374

2311-
/** Data Sgroup Data. */
2375+
/** Data Sgroup Data End. */
23122376
M_SED,
23132377

23142378
/** Sgroup Hierarchy Information. */
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
ACCLDraw01082010302D
3+
4+
5 3 0 0 0 0 0 0 0 0999 V2000
5+
11.0625 -6.2500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
6+
12.0854 -5.6594 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
7+
12.0854 -4.4780 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
8+
13.1085 -6.2502 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
9+
8.3750 -6.2500 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0
10+
1 2 1 0 0 0 0
11+
2 3 2 0 0 0 0
12+
2 4 1 0 0 0 0
13+
M STY 3 1 COM 2 COM 3 DAT
14+
M SLB 3 1 1 2 2 3 3
15+
M SPL 1 3 2
16+
M SAL 1 4 1 2 3 4
17+
M SDI 1 4 10.3747 -6.9814 10.3747 -3.7468
18+
M SDI 1 4 14.1683 -3.7468 14.1683 -6.9814
19+
M SAL 2 1 5
20+
M SDI 2 4 7.6900 -6.9812 7.6900 -5.5188
21+
M SDI 2 4 9.5836 -5.5188 9.5836 -6.9812
22+
M SDT 3 WEIGHT_PERCENT N %
23+
M SDD 3 0.0000 0.0000 DR ALL 1 1
24+
M SED 3 33%
25+
M END

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

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
* */
2525
package org.openscience.cdk.io;
2626

27+
import jdk.internal.util.xml.impl.Input;
2728
import org.hamcrest.CoreMatchers;
2829
import org.junit.Assert;
2930
import org.junit.BeforeClass;
@@ -1835,6 +1836,7 @@ public void testBadAtomCoordinateFormat() throws Exception {
18351836
}
18361837
}
18371838

1839+
18381840
@Test public void atomList() throws Exception {
18391841
try (InputStream in = getClass().getResourceAsStream("query_atomlist.mol");
18401842
MDLV2000Reader mdlr = new MDLV2000Reader(in)) {
@@ -1886,14 +1888,46 @@ public void checkFuseBondWithFewerBondsThanAtoms() throws IOException, CDKExcept
18861888
assertThat(mol.getAtomCount(), is(108));
18871889
}
18881890
}
1891+
18891892
@Test
18901893
public void atomlistWithAtomContainer() throws Exception {
18911894
try (InputStream in = getClass().getResourceAsStream("query_notatomlist.mol");
18921895
MDLV2000Reader mdlr = new MDLV2000Reader(in)) {
18931896

1894-
IAtomContainer mol = mdlr.read(SilentChemObjectBuilder.getInstance().newAtomContainer());
1895-
IAtom deref = AtomRef.deref(mol.getAtom(0));
1897+
IAtomContainer mol = mdlr.read(SilentChemObjectBuilder.getInstance().newAtomContainer());
1898+
IAtom deref = AtomRef.deref(mol.getAtom(0));
18961899
assertThat(deref, CoreMatchers.<IAtom>instanceOf(QueryAtom.class));
18971900
}
18981901
}
1902+
1903+
@Test
1904+
public void dataSgroup() {
1905+
String path = "/data/mdl/hbr_acoh_mix.mol";
1906+
try (InputStream in = getClass().getResourceAsStream(path)) {
1907+
MDLV2000Reader mdlr = new MDLV2000Reader(in);
1908+
IChemObjectBuilder builder = SilentChemObjectBuilder.getInstance();
1909+
IAtomContainer mol = mdlr.read(builder.newAtomContainer());
1910+
List<Sgroup> sgroups = mol.getProperty(CDKConstants.CTAB_SGROUPS);
1911+
Sgroup dataSgroup = null;
1912+
for (Sgroup sgroup : sgroups) {
1913+
if (sgroup.getType() == SgroupType.CtabData) {
1914+
dataSgroup = sgroup;
1915+
break;
1916+
}
1917+
}
1918+
assertNotNull(dataSgroup);
1919+
assertThat(dataSgroup.<String>getValue(SgroupKey.DataFieldName),
1920+
CoreMatchers.is("WEIGHT_PERCENT"));
1921+
// note it looks like MDL/Accelys/BIOVIA simply omit units/format
1922+
// but check we pass it okay
1923+
assertThat(dataSgroup.<String>getValue(SgroupKey.DataFieldUnits),
1924+
CoreMatchers.is("%"));
1925+
assertThat(dataSgroup.<String>getValue(SgroupKey.DataFieldFormat),
1926+
CoreMatchers.is("N"));
1927+
assertThat(dataSgroup.<String>getValue(SgroupKey.Data),
1928+
CoreMatchers.is("33%"));
1929+
} catch (IOException | CDKException e) {
1930+
e.printStackTrace();
1931+
}
1932+
}
18991933
}

tool/sdg/src/main/java/org/openscience/cdk/layout/AtomPlacer.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,8 @@ public Vector2d getNextBondVector(IAtom atom, IAtom previousAtom, Point2d distan
458458
final Point2d a = previousAtom.getPoint2d();
459459
final Point2d b = atom.getPoint2d();
460460

461-
if (isColinear(atom, molecule.getConnectedBondsList(atom))) {
461+
List<IBond> bonds = molecule.getConnectedBondsList(atom);
462+
if (isColinear(atom, bonds)) {
462463
return new Vector2d(b.x-a.x, b.y-a.y);
463464
}
464465

@@ -468,11 +469,15 @@ public Vector2d getNextBondVector(IAtom atom, IAtom previousAtom, Point2d distan
468469

469470
if (isTerminalD4(atom))
470471
addAngle = Math.toRadians(45);
471-
else
472+
else if (isColinear(atom, bonds))
473+
addAngle = Math.toRadians(180);
474+
else if (Elements.isMetal(atom))
475+
addAngle = (2 * Math.PI) / bonds.size();
476+
else {
472477
addAngle = Math.toRadians(120);
473-
474-
if (!trans) addAngle = Math.toRadians(60);
475-
if (isColinear(atom, molecule.getConnectedBondsList(atom))) addAngle = Math.toRadians(180);
478+
if (!trans)
479+
addAngle = Math.toRadians(60);
480+
}
476481

477482
angle += addAngle;
478483
Vector2d vec1 = new Vector2d(Math.cos(angle), Math.sin(angle));

0 commit comments

Comments
 (0)