Skip to content

Commit bae2067

Browse files
committed
Merge pull request biojava#381 from abradle/master
Added functionality to write groups to MDL molblocks (as strings)
2 parents 5edfed4 + 7e69a98 commit bae2067

3 files changed

Lines changed: 156 additions & 1 deletion

File tree

biojava-structure/src/main/java/org/biojava/nbio/structure/Group.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,4 +330,9 @@ public interface Group {
330330
*/
331331
public void trimToSize();
332332

333+
/**
334+
* Function to get the Group as an MDL molblock
335+
* @return the string of the MDL molblock
336+
*/
337+
public String toSDF();
333338
}

biojava-structure/src/main/java/org/biojava/nbio/structure/HetatomImpl.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*/
2424
package org.biojava.nbio.structure;
2525

26+
import org.biojava.nbio.structure.io.GroupToSDF;
2627
import org.biojava.nbio.structure.io.mmcif.ChemCompGroupFactory;
2728
import org.biojava.nbio.structure.io.mmcif.model.ChemComp;
2829
import org.slf4j.Logger;
@@ -525,6 +526,17 @@ public void trimToSize(){
525526
}
526527

527528

528-
}
529+
}
530+
531+
532+
@Override
533+
public String toSDF() {
534+
// Function to return the SDF of a given strucutre
535+
GroupToSDF gts = new GroupToSDF();
536+
return gts.getText(this);
537+
}
538+
539+
540+
529541

530542
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package org.biojava.nbio.structure.io;
2+
3+
import java.text.DecimalFormat;
4+
import java.util.ArrayList;
5+
import java.util.List;
6+
import org.biojava.nbio.structure.Atom;
7+
import org.biojava.nbio.structure.Bond;
8+
import org.biojava.nbio.structure.Group;
9+
10+
11+
public class GroupToSDF {
12+
13+
14+
public String getText(Group thisGroup) {
15+
// Fuction to convert a Group to a strign of the MDL molnlock
16+
StringBuilder sb = new StringBuilder();
17+
sb.append(getHeader(thisGroup));
18+
sb.append(getCtab(thisGroup));
19+
return sb.toString();
20+
}
21+
22+
private String getCtab(Group thisGroup){
23+
DecimalFormat df = new DecimalFormat("0.0000");
24+
// The thre string builders for the three parts of the MDL block
25+
StringBuilder header = new StringBuilder();
26+
StringBuilder atomList = new StringBuilder();
27+
StringBuilder bondOrders = new StringBuilder();
28+
int numBonds = 0;
29+
List<Atom> atoms = thisGroup.getAtoms();
30+
for(Atom a: thisGroup.getAtoms()){
31+
/// ALL SHOULD BE TO FOUR DECIMAL PLACES WITH A CERTAIN NUMBER OF SPACES BEFOREa
32+
String spaceX = getSpace(10, df.format(a.getX()));
33+
String spaceY = getSpace(10, df.format(a.getY()));
34+
String spaceZ = getSpace(10, df.format(a.getZ()));
35+
String spaceEle = getSpace(4, a.getElement().toString());
36+
atomList.append(spaceX+df.format(a.getX())+spaceY+df.format(a.getY())+spaceZ+df.format(a.getZ())+" "+a.getElement().toString()+spaceEle+"0 0 0 0 0 0 0 0 0 0 0 0\n");
37+
for(Bond b: a.getBonds()){
38+
Atom otherAtom = b.getOther(a);
39+
if(atoms.indexOf(otherAtom)>=atoms.indexOf(a)){
40+
continue;
41+
}
42+
if(atoms.indexOf(otherAtom)<0){
43+
continue;
44+
}
45+
if(atoms.indexOf(a)<0){
46+
continue;
47+
}
48+
numBonds++;
49+
// Deal with the index infromation
50+
String indexOther = Integer.toString(atoms.indexOf(otherAtom)+1);
51+
String index = Integer.toString(atoms.indexOf(a)+1);
52+
String order = Integer.toString(b.getBondOrder());
53+
String spaceIndOne = getSpace(3, index);
54+
String spaceIndTwo = getSpace(3, indexOther);
55+
String spaceOrder = getSpace(3, order);
56+
bondOrders.append(spaceIndOne+index+spaceIndTwo+indexOther+spaceOrder+order+" 0\n");
57+
}
58+
}
59+
StringBuilder outString = new StringBuilder();
60+
// Add the first line now
61+
String spaceNumAtoms = getSpace(3, Integer.toString(thisGroup.getAtoms().size()));
62+
String spaceNumBonds = getSpace(3, Integer.toString(numBonds));
63+
header.append("\n");
64+
header.append(spaceNumAtoms+thisGroup.getAtoms().size()+spaceNumBonds+numBonds+" 0 0 0 0 0 0 0 0999 V2000\n");
65+
// Now add the header, atom, bond and charge information togeyher
66+
outString.append(header.toString());
67+
outString.append(atomList.toString());
68+
outString.append(bondOrders.toString());
69+
outString.append(getCharges(thisGroup));
70+
// Add the final line and the $$$$ delimiter
71+
outString.append("M END\n$$$$");
72+
// Get the string and return it
73+
return outString.toString();
74+
}
75+
76+
private Object getCharges(Group thisGroup) {
77+
// Get the array of charges
78+
List<Number> chargeList = getAtomCharges(thisGroup);
79+
// Build the string
80+
StringBuilder outS = new StringBuilder();
81+
int chargeCount=0;
82+
// Loop through the charges -> maximum 8 charges per line
83+
for(int i =0; i<chargeList.size();i++){
84+
short charge = (Short) chargeList.get(i);
85+
if(charge!=0){
86+
if(chargeCount==0){
87+
outS.append("M CHG N");
88+
}
89+
outS.append(getSpace(4, Integer.toString(i))+(i+1));
90+
outS.append(getSpace(4, Short.toString(charge))+charge);
91+
chargeCount++;
92+
}
93+
//
94+
if(chargeCount==8){
95+
outS.append("\n");
96+
outS.replace(0, 10, "M CHG "+chargeCount);
97+
chargeCount=0;
98+
}
99+
100+
}
101+
if(chargeCount==0){
102+
return "";
103+
}
104+
// Now add the charge count
105+
outS.replace(0, 10, "M CHG "+chargeCount);
106+
outS.append("\n");
107+
// Now return the string
108+
return outS.toString();
109+
}
110+
111+
private static List<Number> getAtomCharges(Group group) {
112+
// The list to store the answer
113+
List<Number> outArr = new ArrayList<Number>();
114+
// Get the atom charge Information
115+
for(Atom a: group.getAtoms()){
116+
outArr.add(a.getCharge());
117+
}
118+
return outArr;
119+
}
120+
121+
private String getSpace(int inputNum, String format) {
122+
// Function to get the spaces between numbers
123+
StringBuilder sb = new StringBuilder();
124+
for(int i=0; i<(inputNum-format.length());i++){
125+
sb.append(" ");
126+
}
127+
return sb.toString();
128+
}
129+
130+
private String getHeader(Group thisGroup) {
131+
// Make the header info for the start of the block
132+
StringBuilder sb = new StringBuilder();
133+
sb.append(thisGroup.getPDBName()+"\n");
134+
sb.append("Made by BioJava");
135+
sb.append("\n");
136+
return sb.toString();
137+
}
138+
}

0 commit comments

Comments
 (0)