Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update OCL to v2024.4.0 #197

Merged
merged 1 commit into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 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 All @@ -81,7 +80,7 @@
const parser = new SmilesParser();
const coords1 = parser.parseMolecule(smiles).getIDCoordinates();
const coords2 = parser.parseMolecule(smiles).getIDCoordinates();
// TODO: Find a SMILES that goes through the random branch of coordinate invention.

Check warning on line 83 in __tests__/SmilesParser.js

View workflow job for this annotation

GitHub Actions / lint

Unexpected 'todo' comment: 'TODO: Find a SMILES that goes through...'
// expect(coords1).not.toBe(coords2);
expect(coords1).toBe(coords2);
parser.setRandomSeed(1);
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 @@
'@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 @@ -320,7 +324,7 @@
}

function changeGenericEditorArea(code) {
// TODO: find replacements

Check warning on line 327 in scripts/openchemlib/classes.js

View workflow job for this annotation

GitHub Actions / lint

Unexpected 'todo' comment: 'TODO: find replacements'
code = code.replaceAll(
methodRegExp('showWarningMessage'),
'private void showWarningMessage(String msg) {}',
Expand Down Expand Up @@ -499,7 +503,10 @@
}

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 @@
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 {}
}
Loading