はじめに
CDKで記述子計算を行ったのでメモ。CDKの日本語の情報はRDKitに比べると非常に少ない。PythonとJavaという言語の違いも関係しているように思う。とはいえ、JavaDocや過去のバージョンのプログラムを参考に試行錯誤したところ、分子の記述子(Molecular Descriptor)の計算を行うプログラムを作成することができた。
環境
- JDK11
- CDK2.2
プログラム
実行すると222個の記述子がcsvに出力されるはずである。
4種類のDescriptorクラスでエラーとなるが、おそらく3次元座標を必要とする記述子であるにもかかわらず、SDFに3次元座標がないためであろう。
DescriptorEngineTest.java
import org.openscience.cdk.DefaultChemObjectBuilder;
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.io.iterator.IteratingSDFReader;
import org.openscience.cdk.qsar.DescriptorEngine;
import org.openscience.cdk.qsar.DescriptorValue;
import org.openscience.cdk.qsar.IMolecularDescriptor;
import org.openscience.cdk.IImplementationSpecification;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
public class DescriptorEngineTest {
public static void main(String[] argv) throws Exception{
FileReader fr_train = null;
FileWriter fw_train = null;
// 入力SDFの設定
String path = "C:\\ChemSyo\\Jupyter\\data\\";
try {
fr_train = new FileReader(new File(path + "solubility.train.sdf"));
} catch (FileNotFoundException e) {
System.err.println("sdf not found");
System.exit(1);
}
// 出力ファイルの設定
fw_train = new FileWriter(path + "solubility.train.cdk.csv");
DescriptorEngine descriptorEngine = new DescriptorEngine(org.openscience.cdk.qsar.IMolecularDescriptor.class, null);
IteratingSDFReader sdfReaderTrain = new IteratingSDFReader(fr_train, DefaultChemObjectBuilder.getInstance());
boolean isFirst = true;
while (sdfReaderTrain.hasNext()) {
IAtomContainer mol = (IAtomContainer) sdfReaderTrain.next();
descriptorEngine.process(mol);
java.util.List<IImplementationSpecification> list = descriptorEngine.getDescriptorSpecifications();
java.util.ArrayList<String> descriptorList = new java.util.ArrayList<String>();
java.util.ArrayList<Double> descriptorValues = new java.util.ArrayList<Double>();
for (IImplementationSpecification descriptorSpecification : list) {
System.out.println(descriptorSpecification.getImplementationTitle());
DescriptorValue value = (DescriptorValue)mol.getProperty(descriptorSpecification);
if(value != null) {
for (String name : value.getNames()) {
descriptorList.add(name);
}
if (value.getException() != null) {
System.out.println("ERROR!");
System.exit(0);
}
String[] values = value.getValue().toString().split(",");
for (String tmpValue : values){
tmpValue = tmpValue.trim();
descriptorValues.add(Double.parseDouble(tmpValue));
}
}
}
if (isFirst) {
// ヘッダ出力
for (int i = 0; i < descriptorList.size(); i++) {
System.out.println(descriptorList.get(i));
if (i > 0) {
fw_train.write(",");
}
fw_train.write("CDK_" + descriptorList.get(i));
}
isFirst = false;
}
// 記述子計算結果の出力
fw_train.write("\n");
for (int i = 0; i < descriptorValues.size(); i++) {
System.out.println(descriptorValues.get(i));
if (i > 0) {
fw_train.write(",");
}
fw_train.write(String.valueOf(descriptorValues.get(i)));
}
// break;
}
fr_train.close();
fw_train.close();
}
}
別の機会にAtomDescriptorやBondDescriptor等も出力するプログラムも書く予定である。