Skip to content

Commit

Permalink
feat: update OCL to v2024.4.0 (#197)
Browse files Browse the repository at this point in the history
  • Loading branch information
targos committed Apr 10, 2024
1 parent bd21926 commit 70edd49
Show file tree
Hide file tree
Showing 24 changed files with 814 additions and 430 deletions.
3 changes: 1 addition & 2 deletions __tests__/SmilesParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,10 @@ it('should optionally skip coordinate templates', () => {
it('should optionally make hydrogens explicit', () => {
const smiles = '[CH4]';
const molecule = new Molecule(0, 0);
const parserWithoutExplicitH = new SmilesParser({ smartsMode: 'smarts' });
const parserWithoutExplicitH = new SmilesParser();
parserWithoutExplicitH.parseMolecule(smiles, { molecule });
expect(molecule.getAllAtoms()).toBe(1);
const parserWithExplicitH = new SmilesParser({
smartsMode: 'smarts',
makeHydrogenExplicit: true,
});
parserWithExplicitH.parseMolecule(smiles, { molecule });
Expand Down
30 changes: 15 additions & 15 deletions __tests__/molfileAndAtomMapNo.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@ const { readFileSync } = require('fs');

const { Molecule } = require('../minimal');



test('molfile with atomMapNo', () => {
const molfile = readFileSync(
`${__dirname}/data/atomMapNo.mol`,
'utf8',
);
const molfile = readFileSync(`${__dirname}/data/atomMapNo.mol`, 'utf8');
const molecule = Molecule.fromMolfile(molfile);

const newMolfile = molecule.toMolfile();
const atomMapNo = newMolfile.split(/\r?\n/).filter((line) => line.match(/ [OCH] /))
.map(line => line.replace(/.* ([OCH]) .*(.) {2}0 {2}0$/, '$1 $2'));
expect(atomMapNo).toStrictEqual(['O 5', 'C 1', 'C 3', 'C 4', 'H 2'])
const atomMapNo = newMolfile
.split(/\r?\n/)
.filter((line) => line.match(/ [OCH] /))
// eslint-disable-next-line prefer-named-capture-group
.map((line) => line.replace(/.* ([OCH]) .*(.) {2}0 {2}0$/, '$1 $2'));
expect(atomMapNo).toStrictEqual(['O 5', 'C 1', 'C 3', 'C 4', 'H 2']);

const svg = molecule.toSVG(300, 200);
const mapNos = svg.split(/\r?\n/).filter((line) => line.includes('data-atom-map')).map(line => line.replace(/.*atom-map-no="(.).*/, '$1'));
expect(mapNos).toStrictEqual(["5", "1", "3", "4", "2"])



})
const mapNos = svg
.split(/\r?\n/)
.filter((line) => line.includes('data-atom-map'))
.map((line) =>
line.replace(/.*atom-map-no="(?<atom_map_no>.).*/, '$<atom_map_no>'),
);
expect(mapNos).toStrictEqual(['5', '1', '3', '4', '2']);
});
2 changes: 1 addition & 1 deletion openchemlib
Submodule openchemlib updated 45 files
+1 −1 buildOpenChemLib
+2 −2 pom.xml
+9 −1 src/main/java/com/actelion/research/chem/AbstractDepictor.java
+3 −6 src/main/java/com/actelion/research/chem/AtomTypeList.java
+62 −7 src/main/java/com/actelion/research/chem/Canonizer.java
+20 −51 src/main/java/com/actelion/research/chem/ExtendedMolecule.java
+29 −3 src/main/java/com/actelion/research/chem/ExtendedMoleculeFunctions.java
+43 −5 src/main/java/com/actelion/research/chem/Molecule.java
+1 −2 src/main/java/com/actelion/research/chem/MoleculeStandardizer.java
+451 −206 src/main/java/com/actelion/research/chem/SmilesParser.java
+22 −22 src/main/java/com/actelion/research/chem/StructureSearch.java
+94 −177 src/main/java/com/actelion/research/chem/chemicalspaces/ChemicalSpaceCreator.java
+278 −0 src/main/java/com/actelion/research/chem/chemicalspaces/ptree/PharmTreeSynthonReactionHelper.java
+1,054 −0 src/main/java/com/actelion/research/chem/chemicalspaces/ptree/search/FragmentPTreeSearch.java
+341 −0 src/main/java/com/actelion/research/chem/chemicalspaces/ptree/search/SynthonPharmTreeGenerator.java
+130 −0 src/main/java/com/actelion/research/chem/chemicalspaces/ptree/synthon/PharmTreeSynthon.java
+55 −0 src/main/java/com/actelion/research/chem/chemicalspaces/ptree/synthon/PharmTreeSynthonLibrary.java
+4 −2 src/main/java/com/actelion/research/chem/chemicalspaces/synthon/SynthonCreator.java
+10 −54 src/main/java/com/actelion/research/chem/descriptor/DescriptorHandlerFlexophore.java
+1 −0 src/main/java/com/actelion/research/chem/descriptor/flexophore/MolDistHistHelper.java
+1 −0 src/main/java/com/actelion/research/chem/descriptor/flexophore/PPNodeVizHelper.java
+66 −6 ...ion/research/chem/descriptor/flexophore/completegraphmatcher/ObjectiveBlurFlexophoreHardMatchUncovered.java
+225 −0 src/main/java/com/actelion/research/chem/descriptor/flexophore/generator/ConformerGeneratorStageTries.java
+145 −175 src/main/java/com/actelion/research/chem/descriptor/flexophore/generator/CreatorMolDistHistViz.java
+27 −0 ...in/java/com/actelion/research/chem/descriptor/flexophore/generator/ExceptionTimeOutConformerGeneration.java
+28 −44 src/main/java/com/actelion/research/chem/descriptor/flexophore/redgraph/SubGraphExtractor.java
+3 −2 src/main/java/com/actelion/research/chem/descriptor/pharmacophoretree/PharmacophoreTreeGenerator.java
+1 −1 src/main/java/com/actelion/research/chem/interactionstatistics/InteractionDistanceStatistics.java
+1 −1 src/main/java/com/actelion/research/chem/io/AbstractParser.java
+3 −5 src/main/java/com/actelion/research/chem/io/CompoundFileHelper.java
+1 −0 src/main/java/com/actelion/research/chem/io/CompoundTableConstants.java
+1 −0 src/main/java/com/actelion/research/chem/io/DWARFileCreator.java
+6 −84 src/main/java/com/actelion/research/chem/mcs/BondVector2IdCode.java
+3 −5 src/main/java/com/actelion/research/chem/properties/fractaldimension/FractalDimensionMoleculeMain.java
+4 −2 src/main/java/com/actelion/research/chem/reaction/ReactionClassifier.java
+12 −9 src/main/java/com/actelion/research/chem/reaction/ReactionEncoder.java
+1 −1 src/main/java/com/actelion/research/gui/JProgressDialog.java
+1 −1 src/main/java/com/actelion/research/gui/clipboard/ClipboardHandler.java
+1 −1 src/main/java/com/actelion/research/gui/dock/JDockingPanel.java
+37 −3 src/main/java/com/actelion/research/gui/editor/AtomQueryFeatureDialogBuilder.java
+4 −4 src/main/java/info/clearthought/layout/TableLayoutConstraints.java
+7 −8 src/main/java/org/openmolecules/chem/conf/gen/ConformerSetDiagnostics.java
+4 −2 src/main/java/org/openmolecules/chem/conf/so/ConformationSelfOrganizer.java
+22 −7 src/main/java/org/openmolecules/chem/conf/so/TetrahedralStereoRule.java
+1 −1 src/main/java/smile/LICENSE
22 changes: 21 additions & 1 deletion scripts/openchemlib/classes.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ const changed = [
'@org/openmolecules/chem/conf/gen/ConformerGenerator',
changeConformerGenerator,
],
[
'@org/openmolecules/chem/conf/so/ConformationSelfOrganizer',
changeConformationSelfOrganizer,
],
[
'@org/openmolecules/chem/conf/so/SelfOrganizedConformer',
changeSelfOrganizedConformer,
Expand Down Expand Up @@ -499,7 +503,10 @@ function changeBondLengthSet(code) {
}

function changeConformerSetDiagnostics(code) {
code = code.replace(methodRegExp('writeEliminationRuleFile'), '');
code = code.replaceAll(
/BufferedWriter writer = new BufferedWriter.*/g,
'BufferedWriter writer = new BufferedWriter();',
);
return code;
}

Expand Down Expand Up @@ -659,3 +666,16 @@ function fixCompoundFileHelper(code) {
code = code.replaceAll('file.getName()', '""');
return code;
}

function changeConformationSelfOrganizer(code) {
code = code.replace('import java.io.FileOutputStream;\n', '');
code = code.replace(
'import java.io.OutputStreamWriter;\nimport java.nio.charset.StandardCharsets;\n',
'',
);
code = code.replace(
/mDWWriter = new BufferedWriter.*/,
'mDWWriter = new BufferedWriter();',
);
return code;
}
Original file line number Diff line number Diff line change
Expand Up @@ -1727,6 +1727,8 @@ else if (hydrogens == Molecule.cAtomQFNot3Hydrogen)
isoStr = append(isoStr, "h<3");
else if (hydrogens == Molecule.cAtomQFNot2Hydrogen+Molecule.cAtomQFNot3Hydrogen)
isoStr = append(isoStr, "h<2");
else if (hydrogens == Molecule.cAtomQFNot0Hydrogen+Molecule.cAtomQFNot3Hydrogen)
isoStr = append(isoStr, "h1-2");
}
if ((queryFeatures & Molecule.cAtomQFCharge) != 0) {
long charge = (queryFeatures & Molecule.cAtomQFCharge);
Expand Down Expand Up @@ -1766,6 +1768,12 @@ else if (neighbours == Molecule.cAtomQFNot0Neighbours+Molecule.cAtomQFNot1Neighb
isoStr = append(isoStr, "n>2");
else if (neighbours == (Molecule.cAtomQFNeighbours & ~Molecule.cAtomQFNot4Neighbours))
isoStr = append(isoStr, "n>3");
else if (neighbours == (Molecule.cAtomQFNot0Neighbours | Molecule.cAtomQFNot3Neighbours | Molecule.cAtomQFNot4Neighbours))
isoStr = append(isoStr, "n1-2");
else if (neighbours == (Molecule.cAtomQFNot0Neighbours | Molecule.cAtomQFNot4Neighbours))
isoStr = append(isoStr, "n1-3");
else if (neighbours == (Molecule.cAtomQFNot0Neighbours | Molecule.cAtomQFNot1Neighbour | Molecule.cAtomQFNot4Neighbours))
isoStr = append(isoStr, "n2-3");
}
if ((queryFeatures & Molecule.cAtomQFENeighbours) != 0) {
long eNegNeighbours = (queryFeatures & Molecule.cAtomQFENeighbours);
Expand All @@ -1791,7 +1799,7 @@ else if (eNegNeighbours == (Molecule.cAtomQFNot0ENeighbours | Molecule.cAtomQFNo
isoStr = append(isoStr, "e>2");
else if (eNegNeighbours == (Molecule.cAtomQFENeighbours & ~Molecule.cAtomQFNot4ENeighbours))
isoStr = append(isoStr, "e>3");
else if (eNegNeighbours == (Molecule.cAtomQFNot0ENeighbours | Molecule.cAtomQFNot3ENeighbours | Molecule.cAtomQFNot3ENeighbours))
else if (eNegNeighbours == (Molecule.cAtomQFNot0ENeighbours | Molecule.cAtomQFNot3ENeighbours | Molecule.cAtomQFNot4ENeighbours))
isoStr = append(isoStr, "e1-2");
else if (eNegNeighbours == (Molecule.cAtomQFNot0ENeighbours | Molecule.cAtomQFNot4ENeighbours))
isoStr = append(isoStr, "e1-3");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ public class Canonizer {

// The following options CONSIDER_DIASTEREOTOPICITY, CONSIDER_ENANTIOTOPICITY
// and CONSIDER_STEREOHETEROTOPICITY have no influence on the idcode,
// i.e. the idcode is the same whether or not one of these options is
// used. However, if you require e.g. a pro-E atom always to appear
// i.e. the idcode is the same whether one of these options is used.
// However, if you require e.g. a pro-E atom always to appear
// before the pro-Z, e.g. because you can distinguish them from the
// encoded coordinates, then you need to use one of these options.
// Of course, pro-R or pro-S can only be assigned, if one of the bonds
Expand Down Expand Up @@ -928,7 +928,7 @@ private void canRecursivelyFindCIPParities() {
while ((mNoOfRanks < mMol.getAtoms()) && paritiesFound) {
for (int atom=0; atom<mMol.getAtoms(); atom++) {
mCanBase[atom].init(atom);
mCanBase[atom].add(mAtomBits+4, (mCanRank[atom] << 4)
mCanBase[atom].add(mAtomBits+4, ((long)mCanRank[atom] << 4)
| (mTHParity[atom] << 2));
}

Expand Down Expand Up @@ -987,9 +987,9 @@ private void canRecursivelyFindCanonizedParities() {
// then only consider the ESR type and the rank of the group.

if (!mTHESRTypeNeedsNormalization[atom]
&& mTHESRType[atom] != Molecule.cESRTypeAbs)
&& mTHESRType[atom] != Molecule.cESRTypeAbs)
mCanBase[atom].add((mTHESRType[atom] << 18)
+ (groupRank[(mTHESRType[atom] == Molecule.cESRTypeAnd) ? 0 : 1][mTHESRGroup[atom]] << 8));
+ ((long)groupRank[(mTHESRType[atom] == Molecule.cESRTypeAnd) ? 0 : 1][mTHESRGroup[atom]] << 8));

// if (!mTHParityNeedsNormalization[atom]) {
int parity = mTHParity[atom];
Expand Down Expand Up @@ -1665,6 +1665,14 @@ private boolean canCalcTHParity(int atom, int mode) {
if (mMol.getAtomicNo(atom) == 5 && mMol.getAllConnAtoms(atom) != 4)
return false;

if (mMol.isFragment()) { // don't calculate parities if atom or some neighbours are exclude groups
if ((mMol.getAtomQueryFeatures(atom) & Molecule.cAtomQFExcludeGroup) != 0)
return false;
for (int i=0; i<mMol.getAllConnAtoms(atom); i++)
if ((mMol.getAtomQueryFeatures(mMol.getConnAtom(atom, i)) & Molecule.cAtomQFExcludeGroup) != 0)
return false;
}

// don't consider tetrahedral nitrogen, unless found to qualify for parity calculation
if (mMol.getAtomicNo(atom) == 7
&& !mNitrogenQualifiesForParity[atom])
Expand Down Expand Up @@ -2077,6 +2085,15 @@ private boolean canCalcEZParity(int bond, int mode) {
if (mEZParity[bond] != 0)
return false;

if (mMol.isFragment()) { // don't calculate parities if some bond atoms or their neighbours are exclude groups
for (int i=0; i<2; i++) {
int atom = mMol.getBondAtom(i, bond);
for (int j=0; j<mMol.getAllConnAtoms(atom); j++)
if ((mMol.getAtomQueryFeatures(mMol.getConnAtom(atom, j)) & Molecule.cAtomQFExcludeGroup) != 0)
return false;
}
}

if (mMol.getBondOrder(bond) == 1)
return canCalcBINAPParity(bond, mode);

Expand Down Expand Up @@ -2503,8 +2520,8 @@ else if (order == 2) {

/**
* If the molecule contains exactly one stereo center and if that has unknown configuration,
* than assume that the configuration is meant to be racemic and update molecule accordingly.
* If stereo configuration is ill defined with a stereo bond whose pointed tip is not at the
* then assume that the configuration is meant to be racemic and update molecule accordingly.
* If stereo configuration is ill-defined with a stereo bond whose pointed tip is not at the
* stereo center, then the molecule is not touched and the stereo center kept as undefined.
* @return whether a stereo center was converted to be racemic
*/
Expand Down Expand Up @@ -3753,6 +3770,25 @@ public int getTHParity(int atom) {
}


/**
* Returns the atom's enhanced stereo representation type.
* @param atom
* @return one of the Molecule.cESRTypeXXX constants
*/
public int getTHESRType(int atom) {
return mTHESRType[atom];
}


/**
* @param atom
* @return whether this atom's TH-parity is pseudo
*/
public boolean isPseudoTHParity(int atom) {
return mTHParityIsPseudo[atom];
}


/**
* Returns the absolute bond parity, which is based on priority ranks.
* @param bond
Expand All @@ -3763,6 +3799,25 @@ public int getEZParity(int bond) {
}


/**
* Returns the bond's enhanced stereo representation type.
* @param bond
* @return one of the Molecule.cESRTypeXXX constants
*/
public int getEZESRType(int bond) {
return mEZESRType[bond];
}


/**
* @param bond
* @return whether this bond's EZ-parity is pseudo
*/
public boolean isPseudoEZParity(int bond) {
return mEZParityIsPseudo[bond];
}


/**
* If mMode includes CREATE_PSEUDO_STEREO_GROUPS, then this method returns
* the number of independent relative stereo feature groups. A relative stereo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,7 @@

import com.actelion.research.util.Angle;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.*;
import java.util.Arrays;

/**
Expand Down Expand Up @@ -212,7 +209,7 @@ public int[] copyMoleculeByBonds(ExtendedMolecule destMol, boolean[] includeBond
destMol.mAllAtoms = 0;
for (int atom=0; atom<mAllAtoms;atom++) {
atomMap[atom] = -1;
for (int i=0; i< mConnAtoms[atom]; i++) {
for (int i=0; i<mConnAtoms[atom]; i++) {
if (includeBond[mConnBond[atom][i]]) {
atomMap[atom] = copyAtom(destMol, atom, 0, 0);

Expand Down Expand Up @@ -294,35 +291,30 @@ && isAtomStereoCenter(atom)) {
int lostStereoBond = -1;
int lostAtom = -1;
for (int i=0; i<mAllConnAtoms[atom]; i++) {
//if (mConnAtom.length>=atom || atomMap.length>=mConnAtom[atom][i])
// System.out.println("mConnAtom.length:"+mConnAtom.length+" atom:"+atom+" atomMap.length:"+atomMap.length+" i:"+i+" mConnAtom[atom][i]:"+mConnAtom[atom][i]+" mAtoms:"+mAtoms+" mAllAtoms:"+mAllAtoms);
if (atomMap.length>mConnAtom[atom][i]
&& atomMap[mConnAtom[atom][i]] != -1)
if (bondMap[mConnBond[atom][i]] != -1)
remainingNeighbours++;
else if (mConnBondOrder[atom][i] == 1
&& isStereoBond(mConnBond[atom][i])
&& mBondAtom[0][mConnBond[atom][i]] == atom) {
&& isStereoBond(mConnBond[atom][i])
&& mBondAtom[0][mConnBond[atom][i]] == atom) {
lostStereoBond = mConnBond[atom][i];
lostAtom = mConnAtom[atom][i];
}
}
}
if (lostStereoBond != -1
&& remainingNeighbours >= 3) {
if (lostStereoBond != -1 && remainingNeighbours >= 3) {
double angle = getBondAngle(atom, lostAtom);
double minAngleDif = 10.0;
int minConnBond = -1;
for (int i=0; i<mAllConnAtoms[atom]; i++) {
if (mConnBondOrder[atom][i] == 1
&& (!isStereoBond(mConnBond[atom][i]) || mBondAtom[0][mConnBond[atom][i]] == atom)
&& atomMap.length>mConnAtom[atom][i]
&& atomMap[mConnAtom[atom][i]] != -1) {
&& (!isStereoBond(mConnBond[atom][i]) || mBondAtom[0][mConnBond[atom][i]] == atom)
&& bondMap[mConnBond[atom][i]] != -1) {
double angleDif = Math.abs(getAngleDif(angle, getBondAngle(atom, mConnAtom[atom][i])));
if (minAngleDif > angleDif) {
minAngleDif = angleDif;
minConnBond = mConnBond[atom][i];
}
}
}
}
if (minConnBond != -1) {
int destBond = bondMap[minConnBond];
destMol.setBondType(destBond, mBondType[minConnBond] == cBondTypeUp ? cBondTypeDown : cBondTypeUp);
Expand Down Expand Up @@ -629,7 +621,7 @@ public int getNonHydrogenNeighbourCount(int atom) {
public int getExcludedNeighbourCount(int atom) {
int count = 0;
for (int i=0; i<mConnAtoms[atom]; i++)
if ((mAtomQueryFeatures[i] & Molecule.cAtomQFExcludeGroup) != 0)
if ((mAtomQueryFeatures[mConnAtom[atom][i]] & Molecule.cAtomQFExcludeGroup) != 0)
count++;
return count;
}
Expand Down Expand Up @@ -4070,7 +4062,14 @@ else if ((mAtomQueryFeatures[atom] & cAtomQFAromatic) != 0)
mAtomQueryFeatures[atom] &= ~cAtomQFNotChain; // redundant

if (mAtomCharge[atom] != 0) // explicit charge supersedes query features
mAtomFlags[atom] &= ~cAtomQFCharge;
mAtomQueryFeatures[atom] &= ~cAtomQFCharge;

if (getOccupiedValence(atom) == getMaxValence(atom)) {
mAtomQueryFeatures[atom] &= ~cAtomQFNeighbours;
mAtomQueryFeatures[atom] &= ~cAtomQFENeighbours;
mAtomQueryFeatures[atom] &= ~cAtomQFHydrogen;
mAtomQueryFeatures[atom] &= ~cAtomQFPiElectrons;
}
}
}

Expand Down Expand Up @@ -4107,37 +4106,7 @@ else if (bondType == cBondTypeDelocalized)
}
}


private void writeObject(ObjectOutputStream stream) throws IOException {}
private void readObject(ObjectInputStream stream) throws IOException {}


public final static Coordinates getCenterGravity(ExtendedMolecule mol) {

int n = mol.getAllAtoms();

int [] indices = new int [n];

for (int i = 0; i < indices.length; i++) {
indices[i]=i;
}

return getCenterGravity(mol, indices);
}

public final static Coordinates getCenterGravity(ExtendedMolecule mol, int[] indices) {

Coordinates c = new Coordinates();
for (int i = 0; i < indices.length; i++) {
c.x += mol.getAtomX(indices[i]);
c.y += mol.getAtomY(indices[i]);
c.z += mol.getAtomZ(indices[i]);
}
c.x /= indices.length;
c.y /= indices.length;
c.z /= indices.length;

return c;
}

private void readObject(ObjectInputStream stream) throws IOException {}
}

0 comments on commit 70edd49

Please sign in to comment.