com.actelion.research.chem.phesa.PheSAAlignmentOptimizer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of openchemlib Show documentation
Show all versions of openchemlib Show documentation
Open Source Chemistry Library
package com.actelion.research.chem.phesa;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;
import com.actelion.research.calc.Matrix;
import com.actelion.research.chem.Coordinates;
import com.actelion.research.chem.Molecule;
import com.actelion.research.chem.StereoMolecule;
import com.actelion.research.chem.conf.Conformer;
import com.actelion.research.chem.phesa.pharmacophore.PPTriangle;
import com.actelion.research.chem.phesa.pharmacophore.PPTriangleCreator;
import com.actelion.research.chem.phesa.pharmacophore.PPTriangleMatcher;
import com.actelion.research.chem.phesa.pharmacophore.PPTriangleMatcher.AlignmentResult;
public class PheSAAlignmentOptimizer {
private static int OPTIMIZATIONS = 20;
private PheSAAlignmentOptimizer() {}
public static double alignTwoMolsInPlace(StereoMolecule refMol, StereoMolecule fitMol) {
return alignTwoMolsInPlace(refMol,fitMol,0.5);
}
public static double alignTwoMolsInPlace(StereoMolecule refMol, StereoMolecule fitMol, double ppWeight) {
double similarity = 0.0;
MolecularVolume refVol = new MolecularVolume(refMol);
MolecularVolume fitVol = new MolecularVolume(fitMol);
Coordinates origCOM = new Coordinates(refVol.getCOM());
Conformer refConf = new Conformer(refMol);
Conformer fitConf = new Conformer(fitMol);
Matrix rotation = PheSAAlignment.preProcess(refConf, refVol);
rotation = rotation.getTranspose();
PheSAAlignment.preProcess(fitConf, fitVol);
Map> refTriangles = PPTriangleCreator.create(refVol.getPPGaussians(), refVol.getCOM());
Map> fitTriangles = PPTriangleCreator.create(fitVol.getPPGaussians(), fitVol.getCOM());
List results = PPTriangleMatcher.getMatchingTransforms(refTriangles, fitTriangles,0,0);
double[] bestTransformTriangle = new double[7];
double[] bestTransformPMI = new double[7];
StereoMolecule bestMatch = fitMol;
double bestScoreTriangle = 0.0;
if(results.size()!=0) { // found triangle alignments
results.sort((c1,c2) -> {
return Double.compare(c1.getSimilarity(),c2.getSimilarity());
});
AlignmentResult[] bestAlignments = new AlignmentResult[Math.min(results.size(),OPTIMIZATIONS)];
for(int i=1;ibestScoreTriangle) {
bestScoreTriangle = r[0];
bestTransformTriangle[0] = r[3];
bestTransformTriangle[1] = r[4];
bestTransformTriangle[2] = r[5];
bestTransformTriangle[3] = r[6];
bestTransformTriangle[4] = r[7];
bestTransformTriangle[5] = r[8];
bestTransformTriangle[6] = r[9];
bestMatch = fitMol2;
}
}
}
PheSAAlignment shapeAlignment = new PheSAAlignment(refVol,fitVol, ppWeight);
double[] r = shapeAlignment.findAlignment(PheSAAlignment.initialTransform(2),true);
if(r[0]>bestScoreTriangle) { //alignment found by PMI initial alignment is better
similarity = r[0];
bestTransformPMI = new double[] {r[3],r[4], r[5], r[6], r[7], r[8], r[9]};
bestMatch = fitConf.toMolecule();
PheSAAlignment.rotateMol(bestMatch, bestTransformPMI);
for(int a=0;a0.0) {
similarity = bestScoreTriangle;
result[0] = similarity;
result[1] = triangleRes[1];
result[2] = triangleRes[2];
bestAlignment[0] = bestPairTriangle[0];
bestAlignment[1] = bestPairTriangle[1];
}
else {
for(int i=0;ibestScorePMI) {
bestScorePMI = r[0];
bestTransformPMI = new double[] {r[3],r[4], r[5], r[6], r[7], r[8], r[9]};
bestPairPMI[0] = refVol;
bestPairPMI[1] = fitVol;
}
}
}
//optimize best PMI alignment
PheSAAlignment shapeAlignment = new PheSAAlignment(bestPairPMI[0],bestPairPMI[1],ppWeight);
double[] r = shapeAlignment.findAlignment(new double[][] {bestTransformPMI},true);
if(r[0]>bestScoreTriangle) { //alignment found by PMI initial alignment is better
similarity = r[0];
result[0] = similarity;
result[1] = r[1];
result[2] = r[2];
bestAlignment[0] = refShape.getConformer(bestPairPMI[0]);
bestAlignment[1] = fitShape.getConformer(bestPairPMI[1]);
PheSAAlignment.rotateMol(bestAlignment[1], bestTransformPMI);
}
else {
bestAlignment[0] = bestPairTriangle[0];
bestAlignment[1] = bestPairTriangle[1];
}
}
return result;
}
public static double align(PheSAMolecule fitShape, MolecularVolume refVol, MolecularVolume fitVol, StereoMolecule aligned, double ppWeight) {
Coordinates[] origCoords = new Coordinates[aligned.getAllAtoms()];
IntStream.range(0,aligned.getAllAtoms()).forEach(i -> origCoords[i] = new Coordinates(aligned.getCoordinates(i)));
double[] bestTransformTriangle = new double[7];
double bestScoreTriangle = getTriangleAlignment(fitShape,new MolecularVolume(refVol),new MolecularVolume(fitVol),bestTransformTriangle,aligned,ppWeight);
double bestScorePMI = 0.0;
double[] bestTransformPMI = new double[7];
PheSAAlignment shapeAlignment = new PheSAAlignment(new MolecularVolume(refVol),new MolecularVolume(fitVol), ppWeight);
double[] r = shapeAlignment.findAlignment(PheSAAlignment.initialTransform(2),true);
bestScorePMI = r[0];
bestTransformPMI = new double[] {r[3],r[4], r[5], r[6], r[7], r[8], r[9]};
double similarity = 0.0;
if(bestScorePMI>bestScoreTriangle) { //alignment found by PMI initial alignment is better
IntStream.range(0,aligned.getAllAtoms()).forEach(i -> {
aligned.setAtomX(i, origCoords[i].x);
aligned.setAtomY(i, origCoords[i].y);
aligned.setAtomZ(i, origCoords[i].z);
});
similarity = r[0];
PheSAAlignment.rotateMol(aligned, bestTransformPMI);
}
else {
similarity = bestScoreTriangle;
}
return similarity;
}
private static double[] getBestTriangleAlignment(PheSAMolecule refShape, PheSAMolecule fitShape, StereoMolecule[] bestPairTriangle, double[] bestTransformTriangle, double ppWeight) {
List results = new ArrayList();
double[] res = new double[3];
for(int i=0;i> refTriangles = PPTriangleCreator.create(refVol.getPPGaussians(), refVol.getCOM());
for(int j=0;j> fitTriangles = PPTriangleCreator.create(fitVol.getPPGaussians(),fitVol.getCOM());
results.addAll(PPTriangleMatcher.getMatchingTransforms(refTriangles, fitTriangles,i,j));
}
}
double bestScoreTriangle = 0.0;
if(results.size()!=0) { // found triangle alignments
results.sort((c1,c2) -> {
return Double.compare(c1.getSimilarity(),c2.getSimilarity());
});
AlignmentResult[] bestAlignments = new AlignmentResult[Math.min(results.size(),OPTIMIZATIONS)];
for(int i=1;ibestScoreTriangle) {
bestScoreTriangle = r[0];
res = new double[] {r[0],r[1],r[2]};
bestTransformTriangle[0] = r[3];
bestTransformTriangle[1] = r[4];
bestTransformTriangle[2] = r[5];
bestTransformTriangle[3] = r[6];
bestTransformTriangle[4] = r[7];
bestTransformTriangle[5] = r[8];
bestTransformTriangle[6] = r[9];
bestPairTriangle[1] = fitShape.getConformer(fitVol);
bestPairTriangle[0] = refShape.getConformer(refVol);
}
}
}
if(bestScoreTriangle>0.0)
PheSAAlignment.rotateMol(bestPairTriangle[1], bestTransformTriangle);
return res;
}
private static double getTriangleAlignment(PheSAMolecule fitShape,MolecularVolume refVol_, MolecularVolume fitVol_, double[] bestTransformTriangle, StereoMolecule aligned, double ppWeight) {
MolecularVolume refVol = new MolecularVolume(refVol_);
MolecularVolume fitVol = new MolecularVolume(fitVol_);
List results = new ArrayList();
Map> refTriangles = PPTriangleCreator.create(refVol.getPPGaussians(), refVol.getCOM());
Map> fitTriangles = PPTriangleCreator.create(fitVol.getPPGaussians(),fitVol.getCOM());
results.addAll(PPTriangleMatcher.getMatchingTransforms(refTriangles, fitTriangles,0,0));
double bestScoreTriangle = 0.0;
if(results.size()!=0) { // found triangle alignments
results.sort((c1,c2) -> {
return Double.compare(c1.getSimilarity(),c2.getSimilarity());
});
AlignmentResult[] bestAlignments = new AlignmentResult[Math.min(results.size(),OPTIMIZATIONS)];
for(int i=1;ibestScoreTriangle) {
bestTransform = transform;
bestScoreTriangle = r[0];
bestTransformTriangle[0] = r[3];
bestTransformTriangle[1] = r[4];
bestTransformTriangle[2] = r[5];
bestTransformTriangle[3] = r[6];
bestTransformTriangle[4] = r[7];
bestTransformTriangle[5] = r[8];
bestTransformTriangle[6] = r[9];
}
}
if(bestScoreTriangle>0.0) {
rotate[0] = bestTransform[0];
rotate[1] = bestTransform[1];
rotate[2] = bestTransform[2];
PheSAAlignment.translateMol(aligned, bestTransform[3]);
PheSAAlignment.rotateMol(aligned, rotate);
PheSAAlignment.translateMol(aligned, bestTransform[4]);
PheSAAlignment.rotateMol(aligned, bestTransformTriangle);
}
}
return bestScoreTriangle;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy