Skip to content

Commit

Permalink
MDL V3000 COLLECTIONS
Browse files Browse the repository at this point in the history
  • Loading branch information
fbroda committed Mar 12, 2021
1 parent 760fb5b commit 73058ac
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 17 deletions.
6 changes: 6 additions & 0 deletions docs/examples/cholecalciferol.mol
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ M V30 32 1 19 30 CFG=3
M V30 END BOND
M V30 BEGIN COLLECTION
M V30 MDLV30/STEABS ATOMS=(5 2 12 13 19 22)
M V30 "Ring A" ATOMS=(6 1 2 3 4 5 6) BONDS=(6 1 2 3 4 5 6)
M V30 "Ring C" ATOMS=(6 11 12 13 14 15 16) BONDS=(6 12 13 14 15 16 17)
M V30 "Ring D" ATOMS=(5 12 13 17 18 19) BONDS=(5 13 18 19 20 21)
M V30 "all atoms and bonds" ATOMS=(30 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16-
M V30 17 18 19 20 21 22 23 24 25 26 27 28 29 30) BONDS=(32 1 2 3 4 5 6 7 8 9-
M V30 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32)
M V30 END COLLECTION
M V30 END CTAB
M END
4 changes: 2 additions & 2 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ <h1 id='heading'>MolPaintJS</h1>
molPaintJS.newContext("mol", {helpURL:"help/index.html", iconSize: 32, debugId: "debug"}).init().setMolecule("3-Acetylcoumarin\n MolPaintJS\n\n 14 15 0 0 0 0 0 0 0 0999 V2000\n -2.1434 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n -2.1434 -0.8250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n -1.4289 -1.2375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n -0.7145 -0.8250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n -0.7145 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n -1.4289 0.4125 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n 0.0000 -1.2375 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0\n 0.7145 -0.8250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n 0.7145 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n 0.0000 0.4125 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n 1.4289 0.4125 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n 2.1434 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n 1.4289 1.2375 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0\n 1.4289 -1.2375 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0\n 1 2 2 0 \n 2 3 1 0 \n 3 4 2 0 \n 4 5 1 0 \n 5 6 2 0 \n 6 1 1 0 \n 4 7 1 0 \n 7 8 1 0 \n 8 9 1 0 \n 9 10 2 0 \n 10 5 1 0 \n 9 11 1 0 \n 11 12 1 0 \n 11 13 2 0 \n 8 14 2 0 \nM END\n").setChangeListener(changeListener);

molPaintJS.newContext("viewer", {iconSize: 32, sizeX:250, sizeY:250, viewer: 1}).init().setMolecule(
"n.n.\n MolPaintJS\n\n 12 13 0 0 0 0 999\n -1.4605 1.2342 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n -0.7461 1.6467 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n -0.0316 1.2342 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n 0.6829 1.6467 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n 1.3974 1.2342 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n -1.4605 0.4092 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n -0.7461 -0.0033 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n -0.0316 0.4092 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n 0.6829 -0.0033 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n 1.3974 0.4092 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n 0.6829 2.4717 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0\n 2.1118 -0.0033 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0\n 1 2 1 0\n 2 3 1 0\n 3 4 1 0\n 4 5 1 0\n 6 7 1 0\n 7 8 1 0\n 8 9 1 0\n 9 10 1 0\n 5 10 1 0\n 3 8 1 0\n 4 11 1 1\n 10 12 1 6\n 1 6 2 0\nM END\n");
'\n MolPaint03122111302D\n\n 0 0 0 0 0 0 V3000\nM V30 BEGIN CTAB\nM V30 COUNTS 30 32 0 0 1\nM V30 BEGIN ATOM\nM V30 1 C -2.892959 -2.069151 0.000000 0\nM V30 2 C -2.892959 -2.894151 0.000000 0\nM V30 3 C -2.178488 -3.306651 0.000000 0\nM V30 4 C -1.464017 -2.894151 0.000000 0\nM V30 5 C -1.464017 -2.069151 0.000000 0\nM V30 6 C -2.178488 -1.656651 0.000000 0\nM V30 7 O -3.607430 -3.306651 0.000000 0\nM V30 8 C -0.749546 -1.656651 0.000000 0\nM V30 9 C -2.178488 -0.831651 0.000000 0\nM V30 10 C -1.464017 -0.419151 0.000000 0\nM V30 11 C -1.464017 0.405849 0.000000 0\nM V30 12 C -0.749546 0.818349 0.000000 0\nM V30 13 C -0.749546 1.643349 0.000000 0\nM V30 14 C -1.464017 2.055849 0.000000 0\nM V30 15 C -2.178488 1.643349 0.000000 0\nM V30 16 C -2.178488 0.818349 0.000000 0\nM V30 17 C 0.035075 0.563410 0.000000 0\nM V30 18 C 0.519998 1.230849 0.000000 0\nM V30 19 C 0.035075 1.898288 0.000000 0\nM V30 20 C -0.749546 2.468349 0.000000 0\nM V30 21 H -0.749546 -0.006651 0.000000 0\nM V30 22 C 0.035075 2.723288 0.000000 0\nM V30 23 C 0.749546 3.135788 0.000000 0\nM V30 24 C 1.464017 2.723288 0.000000 0\nM V30 25 C 2.178488 3.135788 0.000000 0\nM V30 26 C 2.892959 2.723288 0.000000 0\nM V30 27 C 3.607430 3.135788 0.000000 0\nM V30 28 C 2.892959 1.898288 0.000000 0\nM V30 29 C -0.548288 3.306651 0.000000 0\nM V30 30 H 0.831964 2.111814 0.000000 0\nM V30 END ATOM\nM V30 BEGIN BOND\nM V30 1 1 1 2\nM V30 2 1 2 3\nM V30 3 1 3 4\nM V30 4 1 4 5\nM V30 5 1 5 6\nM V30 6 1 6 1\nM V30 7 1 2 7 CFG=3\nM V30 8 2 5 8\nM V30 9 2 6 9\nM V30 10 1 9 10\nM V30 11 2 10 11\nM V30 12 1 11 12\nM V30 13 1 12 13\nM V30 14 1 13 14\nM V30 15 1 14 15\nM V30 16 1 15 16\nM V30 17 1 16 11\nM V30 18 1 12 17\nM V30 19 1 17 18\nM V30 20 1 18 19\nM V30 21 1 19 13\nM V30 22 1 13 20 CFG=1\nM V30 23 1 12 21 CFG=3\nM V30 24 1 19 22\nM V30 25 1 22 23\nM V30 26 1 23 24\nM V30 27 1 24 25\nM V30 28 1 25 26\nM V30 29 1 26 27\nM V30 30 1 26 28\nM V30 31 1 22 29 CFG=3\nM V30 32 1 19 30 CFG=3\nM V30 END BOND\nM V30 BEGIN COLLECTION\nM V30 MDLV30/STEABS ATOMS=(5 2 12 13 19 22)\nM V30 "Ring A" ATOMS=(6 1 2 3 4 5 6) BONDS=(6 1 2 3 4 5 6)\nM V30 "Ring C" ATOMS=(6 11 12 13 14 15 16) BONDS=(6 12 13 14 15 16 17)\nM V30 "Ring D" ATOMS=(5 12 13 17 18 19) BONDS=(5 13 18 19 20 21)\nM V30 "all atoms and bonds" ATOMS=(30 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16-\nM V30 17 18 19 20 21 22 23 24 25 26 27 28 29 30) BONDS=(32 1 2 3 4 5 6 7 8 9-\nM V30 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32)\nM V30 END COLLECTION\nM V30 END CTAB\nM END\n');

</script>
<div>Change molecule:
<select id="examples" name="examples" onchange="changeMolecule(document.getElementById('examples').value); return false;">
<option value="v2000_3-acetylcoumarin.mol">3-Acetylcoumarin</option>
<option value="v2000_3-acetylcoumarin.mol" selected>3-Acetylcoumarin</option>
<option value="6-O-acetylhygrophorone_A12.mol">6-O-Acetylhygrophorone A12</option>
<option value="jasmonic_acid.mol">Jasmonic acid</option>
<option value="cholecalciferol.mol">Cholecalciferol</option>
Expand Down
3 changes: 3 additions & 0 deletions src/Context.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ var molPaintJS = (function (molpaintjs) {
var mol;
try {
mol = molPaintJS.MDLParser.parse(st);
if (mol.getCollections().length > 0) {
console.log("collections not supported during paste");
}
} catch(e) {
console.log("Parse error in Context.pasteMolecule(): " + e.message);
console.log("start: line " + e.location.start.line + ", column " + e.location.start.column);
Expand Down
49 changes: 46 additions & 3 deletions src/MDLv3000Writer.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@ var molPaintJS = (function (molpaintjs) {
* @return either concatenation (if combined length is smaller than 79) or st
*/
function extendLine (line, st) {
var lenline = line.length;
if ((line.length + st.length) > 78) {
output += line + '-';
return st;
output += line + "-\n";
return "M V30 " + st;
}
return line + st;
}
Expand All @@ -53,6 +52,10 @@ var molPaintJS = (function (molpaintjs) {

// SGroup

if (mol.getCollections().length > 0) {
writeCollectionBlock(mol);
}

output += 'M V30 END CTAB\n';
}

Expand Down Expand Up @@ -114,6 +117,17 @@ var molPaintJS = (function (molpaintjs) {
return '';
}

function writeAtomList (mol, id, line, count, atoms) {
var st = " " + id + "=(";
st = extendLine(line, st);
st = extendLine(st, "" + count);
for (var a in atoms) {
st = extendLine(st, ' ' + mol.getAtom(a).getIndex());
}
st = extendLine(st, ")");
return st;
}

function writeBondBlock (mol) {
output += "M V30 BEGIN BOND\n";
for (var i in mol.getBonds()) {
Expand All @@ -131,13 +145,42 @@ var molPaintJS = (function (molpaintjs) {
output += "M V30 END BOND\n";
}

function writeBondList (mol, id, line, count, bonds) {
var st = " " + id + "=(";
st = extendLine(line, st);
st = extendLine(st, "" + count);
for (var b in bonds) {
st = extendLine(st, ' ' + mol.getBond(b).getIndex());
}
st = extendLine(st, ")");
return st;
}

function writeBondStereo (bond) {
if (bond.getStereo('v3') != 0) {
return " CFG=" + bond.getStereo('v3');
}
return '';
}

function writeCollectionBlock (mol) {
output += "M V30 BEGIN COLLECTION\n";
for (var collection of mol.getCollections()) {
var st = "M V30 ";
st = extendLine(st, '"' + collection.getName() + '" ');
var count = Object.keys(collection.getAtoms()).length;
if (count > 0) {
st = writeAtomList(mol, 'ATOMS', st, count, collection.getAtoms());
}
count = Object.keys(collection.getBonds()).length;
if (count > 0) {
st = writeBondList(mol, 'BONDS', st, count, collection.getBonds());
}
output += st + '\n';
}
output += "M V30 END COLLECTION\n";
}

return {
write : function (mol) {

Expand Down
6 changes: 5 additions & 1 deletion src/Molecule.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
var molPaintJS = (function (molpaintjs) {
"use strict";

/*
* ToDo: history for collections, removal and replacement of
* atoms and bonds in collections
*/
molpaintjs.Molecule = function() {

var properties = {};
Expand Down Expand Up @@ -66,7 +70,7 @@ var molPaintJS = (function (molpaintjs) {
addCollection : function (collection) {
var merged = false;
for (var c of collections) {
if (c.name == collection.name) {
if (c.getName() == collection.getName()) {
c.merge(collection);
merged = true;
}
Expand Down
4 changes: 2 additions & 2 deletions src/PointerTool.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* MolPaintJS
* Copyright 2017 Leibniz-Institut f. Pflanzenbiochemie
* Copyright 2017 - 2021 Leibniz-Institut f. Pflanzenbiochemie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -57,7 +57,7 @@ var molPaintJS = (function (molpaintjs) {
if(evt.shiftKey || evt.ctrlKey) {
context.getMolecule().clearSelection(1);
} else {
context.getMolecule().clearSelection(3);
context.getMolecule().clearSelection(7);
}
} else {
// transform mode; prepare history
Expand Down
47 changes: 40 additions & 7 deletions src/ctab.pegjs
Original file line number Diff line number Diff line change
Expand Up @@ -774,8 +774,34 @@ v3LinkAtomLine

/* ToDo collection block parsing */
v3collectionBlock
= newline 'M V30 BEGIN COLLECTION' newline entry:collectionEntry* 'M V30 END COLLECTION' { logMessage(1, 'ignoring collection block');
// logMessage(1, util.inspect(entry, {showHidden: false, depth: null}));
= newline 'M V30 BEGIN COLLECTION' newline entries:collectionEntry* 'M V30 END COLLECTION' {

entries.forEach(entry => {
// logMessage(1, util.inspect(entry, {showHidden: false, depth: null}));
var collection = molPaintJS.Collection(entry.name);
var atoms = {};
var bonds = {};
for (var data of entry.data) {
if (data['ATOM'] != null) {
for( var a of data['ATOM'].data) {
if (a != null) {
atoms['Atom' + a] = 'Atom' + a;
}
}
}
if (data['BOND'] != null) {
for( var b of data['BOND'].data) {
if (b != null) {
bonds['Bond' + b] = 'Bond' + b;
}
}
}
}
collection.setAtoms(atoms);
collection.setBonds(bonds);
mdlParserData.molecule.addCollection(collection);
});
logMessage(1, 'parsed COLLECTION BLOCK');
}

collectionEntry
Expand All @@ -785,8 +811,8 @@ collectionEntry
/* ToDo multi line lists */
collectionContinuation
= v3LineContinuation cont:collectionContinuation { return cont; }
/ ' '* 'ATOMS=' list:v3CountedUIntList cont:collectionContinuation { return {type:'ATOM', collection:flatten(cont, list) }; }
/ ' '* 'BONDS=' list:v3CountedUIntList cont:collectionContinuation { return {type:'BOND', collection:flatten(cont, list) }; }
/ ' '* 'ATOMS=' list:v3CountedUIntList cont:collectionContinuation { var c = cont || {}; c['ATOM'] = list; return c; }
/ ' '* 'BONDS=' list:v3CountedUIntList cont:collectionContinuation { var c = cont || {}; c['BOND'] = list; return c; }
/ ' '* 'SGROUPS=(' [^)]* ')' collectionContinuation
/ ' '* 'OBJ3DS=(' [^)]* ')' collectionContinuation
/ ' '* 'MEMBERS=(' [^)]* ')' collectionContinuation
Expand Down Expand Up @@ -842,14 +868,21 @@ sign
/ '+' { return 1; }

/* ToDo: quoted strings */

string
= characters:[^ "'\t\n\r]+ { return characters.join(''); }
= '"' str:substring+ '"' { return str.join(''); }
/ !('-' newline) characters:[^ "(\t\n\r]+ { return characters.join(''); }

substring
= !('-' newline) characters:[^"\n\r]+ { return characters.join(''); }
/ '""' { return '"'; }
/ '-' newline { return ''; }

string4
= characters:([^\n\r][^\n\r][^\n\r][^\n\r]) { return characters.join(''); }
= characters:(noNL noNL noNL noNL) { return characters.join(''); }

string3
= characters:([^\n\r][^\n\r][^\n\r]) { return characters.join(''); }
= characters:(noNL noNL noNL) { return characters.join(''); }

whitespaceNL
= whitespace
Expand Down
6 changes: 6 additions & 0 deletions template/examples/cholecalciferol.mol
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ M V30 32 1 19 30 CFG=3
M V30 END BOND
M V30 BEGIN COLLECTION
M V30 MDLV30/STEABS ATOMS=(5 2 12 13 19 22)
M V30 "Ring A" ATOMS=(6 1 2 3 4 5 6) BONDS=(6 1 2 3 4 5 6)
M V30 "Ring C" ATOMS=(6 11 12 13 14 15 16) BONDS=(6 12 13 14 15 16 17)
M V30 "Ring D" ATOMS=(5 12 13 17 18 19) BONDS=(5 13 18 19 20 21)
M V30 "all atoms and bonds" ATOMS=(30 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16-
M V30 17 18 19 20 21 22 23 24 25 26 27 28 29 30) BONDS=(32 1 2 3 4 5 6 7 8 9-
M V30 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32)
M V30 END COLLECTION
M V30 END CTAB
M END
Loading

0 comments on commit 73058ac

Please sign in to comment.