diff --git a/pom.xml b/pom.xml index 90dcf7a0..bddda0a1 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ Please follow the naming scheme YEAR.MONTH.RELEASE_NO_OF_MONTH (eg. 2016.4.1 for second release in Apr 2016) --> - 2024.2.3-SNAPSHOT + 2024.2.4-SNAPSHOT OpenChemLib Open Source Chemistry Library diff --git a/src/main/java/com/actelion/research/chem/ExtendedMoleculeFunctions.java b/src/main/java/com/actelion/research/chem/ExtendedMoleculeFunctions.java index 593f090b..a913dee6 100644 --- a/src/main/java/com/actelion/research/chem/ExtendedMoleculeFunctions.java +++ b/src/main/java/com/actelion/research/chem/ExtendedMoleculeFunctions.java @@ -1163,9 +1163,7 @@ public static boolean isSulfoxyGroup(StereoMolecule mol, int atom) { public static boolean isIsolatedCarbon(StereoMolecule mol, int indexAtCentral, int [] arrIndexAt){ boolean isolated=true; - int nConnected = mol.getConnAtoms(indexAtCentral); - boolean [] arrConnected = new boolean[mol.getAtoms()]; for (int i = 0; i < nConnected; i++) { @@ -1176,7 +1174,6 @@ public static boolean isIsolatedCarbon(StereoMolecule mol, int indexAtCentral, i if(!arrConnected[indexAt]){ continue; } - if(mol.getAtomicNo(indexAt)==6){ isolated=false; break; diff --git a/src/main/java/com/actelion/research/chem/descriptor/flexophore/generator/CreatorMolDistHistViz.java b/src/main/java/com/actelion/research/chem/descriptor/flexophore/generator/CreatorMolDistHistViz.java index 5bfe2999..0643d856 100644 --- a/src/main/java/com/actelion/research/chem/descriptor/flexophore/generator/CreatorMolDistHistViz.java +++ b/src/main/java/com/actelion/research/chem/descriptor/flexophore/generator/CreatorMolDistHistViz.java @@ -36,18 +36,13 @@ import com.actelion.research.calc.ThreadMaster; import com.actelion.research.chem.*; -import com.actelion.research.chem.conf.Conformer; import com.actelion.research.chem.descriptor.DescriptorHandlerFlexophore; import com.actelion.research.chem.descriptor.flexophore.*; import com.actelion.research.chem.descriptor.flexophore.redgraph.SubGraphExtractor; import com.actelion.research.chem.descriptor.flexophore.redgraph.SubGraphIndices; import com.actelion.research.chem.interactionstatistics.InteractionAtomTypeCalculator; -import com.actelion.research.util.TimeDelta; -import org.openmolecules.chem.conf.gen.ConformerGenerator; -import org.openmolecules.chem.conf.gen.RigidFragmentCache; import java.util.*; -import java.util.concurrent.TimeoutException; /** * CreatorMolDistHistViz @@ -58,6 +53,18 @@ public class CreatorMolDistHistViz { private static final boolean DEBUG = DescriptorHandlerFlexophore.DEBUG; + /** + * Aromatic imide structure with an exocyclic N. Two N in the aromatic ring. Results in an extreme electron poor + * exocyclic N. which is not making any interactions. Consequently, it is removed from the subgraph lists. + * The electron poor N is the non-aromatic N in the fragment definitions! + */ + public static final String IDCODE_EXO_N_AROM_IMIDE = "eMPARVCjK|X`"; + + // Imide structure separated by one bond in the aromatic ring + public static final String IDCODE_EXO_N_AROM_IMIDE_ALPHA = "gO|@AfeJih@PA@"; + + public static String [] ARR_EXO_N_AROM_IMIDE = {IDCODE_EXO_N_AROM_IMIDE, IDCODE_EXO_N_AROM_IMIDE_ALPHA}; + /** * Similarity 0.977, similarity for identical molecule and a timeout of 5 min. So timeout of 6 min should be fine. @@ -95,9 +102,10 @@ public class CreatorMolDistHistViz { private boolean onlyOneConformer; private Exception recentException = null; + // Calling SSSearcher frequently generates errors. + // private SSSearcher ssSearcher; - private int [] arrIndexAtomNewTmp; - + private StereoMolecule [] arrElectronPoorN; private ConformerGeneratorStageTries conformerGeneratorStageTries; public CreatorMolDistHistViz() { @@ -106,10 +114,18 @@ public CreatorMolDistHistViz() { conformationMode = CONF_GEN_TS; - arrIndexAtomNewTmp = new int[MAX_NUM_ATOMS]; - conformerGeneratorStageTries = new ConformerGeneratorStageTries(); + IDCodeParser parser = new IDCodeParser(); + + arrElectronPoorN = new StereoMolecule[ARR_EXO_N_AROM_IMIDE.length]; + + for (int i = 0; i < ARR_EXO_N_AROM_IMIDE.length; i++) { + StereoMolecule frag = parser.getCompactMolecule(ARR_EXO_N_AROM_IMIDE[i]); + frag.ensureHelperArrays(Molecule.cHelperRings); + arrElectronPoorN[i]=frag; + } + } public void setThreadMaster(ThreadMaster threadMaster) { @@ -177,6 +193,8 @@ public MolDistHistViz createMultipleConformations(StereoMolecule molOrig, int nC // List liSubGraphIndices = subGraphExtractor.extract(molInPlace); liSubGraphIndices = handleCarbonConnected2Hetero(liSubGraphIndices, molInPlace); + liSubGraphIndices = removeExoCyclicElectronPoorN(liSubGraphIndices, molInPlace); + List liMultCoordFragIndex = new ArrayList<>(); for (SubGraphIndices subGraphIndices : liSubGraphIndices) { @@ -334,6 +352,85 @@ public static List handleCarbonConnected2Hetero(List removeExoCyclicElectronPoorN(List liSubGraphIndices, StereoMolecule molInPlace){ + + List liElectronPoorN = getElectronPoorN(molInPlace); + +// if(liElectronPoorN.size()>0) +// System.out.println("CreatorMolDistHistViz removeExoCyclicElectronPoorN found " + liElectronPoorN.size() + " electron poor atoms in " + molInPlace.getIDCode()); + + boolean [] arrMatchAtom = new boolean[molInPlace.getAtoms()]; + + for (int indexAt : liElectronPoorN) { + arrMatchAtom[indexAt]=true; + } + + List liSubGraphIndicesProcessed = new ArrayList<>(); + for (SubGraphIndices sgi : liSubGraphIndices) { + int[] arrIndexAtomFragment = sgi.getAtomIndices(); + HashSet hsIndexAtom2Remove = new HashSet<>(); + for (int indexAtFrag : arrIndexAtomFragment) { + if (arrMatchAtom[indexAtFrag]) { + hsIndexAtom2Remove.add(indexAtFrag); + } + } + + SubGraphIndices sgiProcessed = new SubGraphIndices(); + if (hsIndexAtom2Remove.size() > 0) { + for (int indexAtFrag : arrIndexAtomFragment) { + if (!hsIndexAtom2Remove.contains(indexAtFrag)) { + sgiProcessed.addIndex(indexAtFrag); + } + } + } else { + sgiProcessed.addIndex(arrIndexAtomFragment); + } + if (sgiProcessed.getNumIndices() > 0) + liSubGraphIndicesProcessed.add(sgiProcessed); + } + return liSubGraphIndicesProcessed; + + + + } + + /** + * The electron poor N is the non-aromatic N! + * @param molInPlace + * @return + */ + private List getElectronPoorN(StereoMolecule molInPlace){ + List liElectronPoorN = new ArrayList<>(); + + // Calling SSSearcher frequently generates errors. + SSSearcher ssSearcher = new SSSearcher(); + ssSearcher.setMolecule(molInPlace); + for (int i = 0; i < arrElectronPoorN.length; i++) { + + ssSearcher.setFragment(arrElectronPoorN[i]); + int numFrags = ssSearcher.findFragmentInMolecule( + SSSearcher.cCountModeOverlapping, + SSSearcher.cMatchDBondToDelocalized | SSSearcher.cMatchAromDBondToDelocalized ); + if(numFrags>0) { + // System.out.println("Found!"); + List li = ssSearcher.getMatchList(); + for (int[] arrIndex : li) { + for (int j = 0; j < arrIndex.length; j++) { + int indAt = arrIndex[j]; + int atNo = molInPlace.getAtomicNo(indAt); + if(atNo==7){ + if(!molInPlace.isAromaticAtom(indAt)){ + liElectronPoorN.add(indAt); + } + } + } + } + } + } + return liElectronPoorN; + } + + /** * Creates the descriptor from the coordinates. * @param liMultCoordFragIndex contains the coordinates and the related atom indices of the molecule