Skip to content

Commit 6cb49c8

Browse files
committed
Merge tag 'openchemlib-2024.10.2'
[maven-release-plugin] copy for tag openchemlib-2024.10.2
2 parents e30c9f8 + 4ba6aeb commit 6cb49c8

20 files changed

+473
-300
lines changed

.github/workflows/maven.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ jobs:
1111
strategy:
1212
matrix:
1313
# test against latest update of each major Java version:
14-
java: [ 8, 11, 17 ]
14+
java: [ 8, 11, 17, 21 ]
1515
name: Java ${{ matrix.java }}
1616
steps:
17-
- uses: actions/checkout@v3
17+
- uses: actions/checkout@v4
1818
- name: Setup java
19-
uses: actions/setup-java@v3
19+
uses: actions/setup-java@v4
2020
with:
2121
distribution: 'zulu'
2222
java-version: ${{ matrix.java }}

pom.xml

+9-11
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
Please follow the naming scheme YEAR.MONTH.RELEASE_NO_OF_MONTH
99
(eg. 2016.4.1 for second release in Apr 2016)
1010
-->
11-
<version>2024.10.1</version>
11+
<version>2024.10.2</version>
1212

1313
<name>OpenChemLib</name>
1414
<description>Open Source Chemistry Library</description>
@@ -48,6 +48,9 @@
4848

4949
<properties>
5050
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
51+
<maven.compiler.target>1.8</maven.compiler.target>
52+
<maven.compiler.source>1.8</maven.compiler.source>
53+
<javafx.version>11.0.2</javafx.version>
5154
</properties>
5255

5356
<!-- Disable doclint for Java 8 -->
@@ -97,17 +100,17 @@
97100
<dependency>
98101
<groupId>org.openjfx</groupId>
99102
<artifactId>javafx-controls</artifactId>
100-
<version>11.0.2</version>
103+
<version>${javafx.version}</version>
101104
</dependency>
102105
<dependency>
103106
<groupId>org.openjfx</groupId>
104107
<artifactId>javafx-swing</artifactId>
105-
<version>11.0.2</version>
108+
<version>${javafx.version}</version>
106109
</dependency>
107110
<dependency>
108111
<groupId>org.openjfx</groupId>
109112
<artifactId>javafx-web</artifactId>
110-
<version>11.0.2</version>
113+
<version>${javafx.version}</version>
111114
</dependency>
112115
</dependencies>
113116
</profile>
@@ -127,12 +130,7 @@
127130
<plugin>
128131
<groupId>org.apache.maven.plugins</groupId>
129132
<artifactId>maven-compiler-plugin</artifactId>
130-
<version>2.0</version>
131-
<configuration>
132-
<source>1.8</source>
133-
<target>1.8</target>
134-
<encoding>UTF-8</encoding>
135-
</configuration>
133+
<version>3.1</version>
136134
</plugin>
137135
<plugin>
138136
<groupId>org.apache.maven.plugins</groupId>
@@ -209,7 +207,7 @@
209207
<connection>scm:git:[email protected]:Actelion/openchemlib.git</connection>
210208
<developerConnection>scm:git:[email protected]:Actelion/openchemlib.git</developerConnection>
211209
<url>https://github.com/Actelion/openchemlib</url>
212-
<tag>openchemlib-2024.10.1</tag>
210+
<tag>openchemlib-2024.10.2</tag>
213211
</scm>
214212

215213
<distributionManagement>

src/main/java/com/actelion/research/chem/Canonizer.java

+12-21
Original file line numberDiff line numberDiff line change
@@ -170,12 +170,12 @@ public class Canonizer {
170170
private boolean[] mNitrogenQualifiesForParity;
171171
private ArrayList<CanonizerFragment> mFragmentList;
172172
private ArrayList<int[]> mTHParityNormalizationGroupList;
173-
private int mMode,mNoOfRanks,mNoOfPseudoGroups;
173+
private final int mMode;
174+
private int mNoOfRanks,mNoOfPseudoGroups;
174175
private boolean mIsOddParityRound;
175-
private boolean mZCoordinatesAvailable,mAllHydrogensAreExplicit;
176+
private final boolean mZCoordinatesAvailable,mAllHydrogensAreExplicit;
176177
private boolean mCIPParityNoDistinctionProblem;
177178
private boolean mEncodeAvoid127;
178-
179179
private boolean mGraphGenerated;
180180
private int mGraphRings,mFeatureBlock;
181181
private int[] mGraphAtom;
@@ -184,9 +184,10 @@ public class Canonizer {
184184
private int[] mGraphFrom;
185185
private int[] mGraphClosure;
186186

187-
private String mIDCode, mEncodedCoords,mMapping;
188-
private StringBuilder mEncodingBuffer;
189-
private int mEncodingBitsAvail,mEncodingTempData,mAtomBits,mMaxConnAtoms;
187+
private String mIDCode, mEncodedCoords,mMapping;
188+
private StringBuilder mEncodingBuffer;
189+
private int mEncodingBitsAvail,mEncodingTempData,mMaxConnAtoms;
190+
private final int mAtomBits;
190191

191192
/**
192193
* Runs a canonicalization procedure for the given molecule that creates unique atom ranks,
@@ -204,7 +205,7 @@ public Canonizer(StereoMolecule mol) {
204205
* If mode includes ENCODE_ATOM_CUSTOM_LABELS, than custom atom labels are
205206
* considered for the atom ranking and are encoded into the idcode.<br>
206207
* If mode includes COORDS_ARE_3D, then getEncodedCoordinates() always returns
207-
* a 3D-encoding even if all z-coordinates are 0.0. Otherwise coordinates are
208+
* a 3D-encoding even if all z-coordinates are 0.0. Otherwise, coordinates are
208209
* encoded in 3D only, if at least one of the z-coords is not 0.0.
209210
* @param mol
210211
* @param mode 0 or one or more of CONSIDER...TOPICITY, CREATE..., ENCODE_ATOM_CUSTOM_LABELS, ASSIGN_PARITIES_TO_TETRAHEDRAL_N, COORDS_ARE_3D
@@ -226,17 +227,7 @@ public Canonizer(StereoMolecule mol, int mode) {
226227

227228
mZCoordinatesAvailable = ((mode & COORDS_ARE_3D) != 0) || mMol.is3D();
228229

229-
mAllHydrogensAreExplicit = false;
230-
if (mMol.getAllAtoms() > mMol.getAtoms()
231-
&& !mMol.isFragment()) {
232-
mAllHydrogensAreExplicit = true;
233-
for (int i=0; i<mMol.getAtoms(); i++) {
234-
if (mMol.getImplicitHydrogens(i) != 0) {
235-
mAllHydrogensAreExplicit = false;
236-
break;
237-
}
238-
}
239-
}
230+
mAllHydrogensAreExplicit = (mMol.getImplicitHydrogens() == 0);
240231

241232
if ((mMode & NEGLECT_ANY_STEREO_INFORMATION) == 0) {
242233
mTHParity = new byte[mMol.getAtoms()];
@@ -639,7 +630,7 @@ private boolean canInnerBreakTiesByHeteroTopicity() {
639630
private void canBreakTiesRandomly() {
640631
for (int atom=0; atom<mMol.getAtoms(); atom++) {
641632
mCanBase[atom].init(atom);
642-
mCanBase[atom].add(mAtomBits+1, 2*mCanRank[atom]);
633+
mCanBase[atom].add(mAtomBits+1, (long)2*mCanRank[atom]);
643634
}
644635

645636
// promote randomly one atom of lowest shared rank.
@@ -895,7 +886,7 @@ private void canRecursivelyFindAllParities() {
895886
thParityInfo |= mTHESRGroup[atom];
896887
}
897888

898-
mCanBase[atom].add(2 * parityInfoBits, thParityInfo << parityInfoBits); // generate space for bond parity
889+
mCanBase[atom].add(2 * parityInfoBits, (long)thParityInfo << parityInfoBits); // generate space for bond parity
899890
}
900891

901892
for (int bond=0; bond<mMol.getBonds(); bond++) {
@@ -3371,7 +3362,7 @@ public String getEncodedCoordinates() {
33713362
* original molecule including coordinates.<br>
33723363
* If keepPositionAndScale==false, then coordinate encoding will be relative,
33733364
* i.e. scale and absolute positions get lost during the encoding.
3374-
* Otherwise the encoding retains scale and absolute positions.<br>
3365+
* Otherwise, the encoding retains scale and absolute positions.<br>
33753366
* If the molecule has 3D-coordinates and if there are no implicit hydrogen atoms,
33763367
* i.e. all hydrogen atoms are explicitly available with their coordinates, then
33773368
* hydrogen 3D-coordinates are also encoded despite the fact that the idcode itself does

src/main/java/com/actelion/research/chem/ExtendedMolecule.java

+25-3
Original file line numberDiff line numberDiff line change
@@ -1445,7 +1445,28 @@ public boolean supportsImplicitHydrogen(int atom) {
14451445
}
14461446

14471447
/**
1448-
* Calculates and return the number of implicit hydrogens at atom.
1448+
* Calculates and returns the number of implicit hydrogens of the molecule.
1449+
* For hydrogens atoms, metals except Al, or a noble gases, 0 is assumed.
1450+
* For all other atom kinds the number of implicit hydrogens is basically
1451+
* the lowest typical valence that is compatible with the occupied valence,
1452+
* minus the occupied valence corrected by atom charge and radical state.
1453+
* If this molecule is a fragment, then 0 is returned.
1454+
* @return number of implicit hydrogens of the molecule
1455+
*/
1456+
public int getImplicitHydrogens() {
1457+
if (mIsFragment)
1458+
return 0;
1459+
1460+
ensureHelperArrays(cHelperNeighbours);
1461+
int implicitHydrogens = 0;
1462+
for (int atom=0; atom<mAtoms; atom++)
1463+
implicitHydrogens += getImplicitHydrogens(atom);
1464+
1465+
return implicitHydrogens;
1466+
}
1467+
1468+
/**
1469+
* Calculates and returns the number of implicit hydrogens at atom.
14491470
* If atom is itself a hydrogen atom, a metal except Al, or a noble gas,
14501471
* then 0 is returned. For all other atom kinds the number of
14511472
* implicit hydrogens is basically the lowest typical valence that is compatible
@@ -1463,8 +1484,9 @@ public int getImplicitHydrogens(int atom) {
14631484
if (!supportsImplicitHydrogen(atom))
14641485
return 0;
14651486

1466-
if ("*".equals(getAtomCustomLabel(atom)))
1467-
return 0;
1487+
// attachment points have at least a valence of 1, i.e. they must be connected to something
1488+
if (mAtomicNo[atom] == 0 || "*".equals(getAtomCustomLabel(atom)))
1489+
return mAllConnAtoms[atom] == 0 ? 1 : 0;
14681490

14691491
ensureHelperArrays(cHelperNeighbours);
14701492

src/main/java/com/actelion/research/chem/IsomericSmilesCreator.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,7 @@ private void appendBondOrderSymbol(int bond, int parentAtom, StringBuilder build
820820
if (mEZHalfParity[bond] != 0)
821821
builder.append(mEZHalfParity[bond] == 1 ? '/' : '\\');
822822
if (mMode == MODE_CREATE_SMARTS) {
823-
int bondTypes = mMol.getBondQueryFeatures(Molecule.cBondQFBondTypes | Molecule.cBondQFRareBondTypes);
823+
int bondTypes = mMol.getBondQueryFeatures(bond) & (Molecule.cBondQFBondTypes | Molecule.cBondQFRareBondTypes);
824824
if (bondTypes != 0) {
825825
if ((bondTypes & Molecule.cBondTypeSingle) != 0 && mEZHalfParity[bond] == 0) {
826826
builder.append('-');

src/main/java/com/actelion/research/chem/SSSearcher.java

+8
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,14 @@ public boolean areBondsSimilar(int moleculeBond, int fragmentBond) {
13221322
&& ringSize == (mMolecule.getBondQueryFeatures(fragmentBond) & Molecule.cBondQFRingSize) >> Molecule.cBondQFRingSizeShift)
13231323
return true;
13241324

1325+
if (ringSize <= 2) { // ring size 8-11 is encoded as 1; ring size >=12 is encoded as 2
1326+
int moleculeRingSize = mMolecule.getBondRingSize(moleculeBond);
1327+
if (ringSize == 1)
1328+
return (moleculeRingSize >= 8) && (moleculeRingSize <= 12);
1329+
else
1330+
return moleculeRingSize >= 12;
1331+
}
1332+
13251333
boolean found = false;
13261334
RingCollection ringSet = mMolecule.getRingSet();
13271335
for (int i=0; i<ringSet.getSize(); i++) {

src/main/java/com/actelion/research/chem/descriptor/DescriptorWeightsHelper.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public DescriptorWeightsHelper() {
7171
* - Charged pp points are set mandatory.
7272
* @param liSubGraphIndices
7373
* @param molecule3D
74-
* @return
74+
* @return array with dimension molecule3D.getAtoms().
7575
*/
7676
public static int [] calcWeightLabels(List<SubGraphIndices> liSubGraphIndices, Molecule3D molecule3D){
7777

src/main/java/com/actelion/research/chem/descriptor/flexophore/MolDistHistViz.java

+35-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import com.actelion.research.chem.interactionstatistics.InteractionAtomTypeCalculator;
4242
import com.actelion.research.chem.phesa.pharmacophore.PharmacophoreCalculator;
4343
import com.actelion.research.chem.phesa.pharmacophore.pp.IPharmacophorePoint;
44+
import com.actelion.research.util.Formatter;
4445
import com.actelion.research.util.graph.complete.ICompleteGraph;
4546

4647
import java.io.Serializable;
@@ -1056,7 +1057,40 @@ public String toStringShort(){
10561057

10571058
return b.toString();
10581059
}
1059-
1060+
1061+
/**
1062+
* Shows the weights
1063+
* @return
1064+
*/
1065+
public String toStringShortWithWeights(){
1066+
1067+
if(!finalized)
1068+
realize();
1069+
StringBuffer b = new StringBuffer();
1070+
1071+
b.append("[");
1072+
for (int i = 0; i < getNumPPNodes(); i++) {
1073+
b.append(Formatter.format1(arrWeight[i]));
1074+
b.append(getNode(i).toStringShort());
1075+
if(i<getNumPPNodes()-1){
1076+
b.append(" ");
1077+
} else {
1078+
b.append("]");
1079+
}
1080+
}
1081+
1082+
for (int i = 0; i < getNumPPNodes(); i++) {
1083+
for (int j = i+1; j < getNumPPNodes(); j++) {
1084+
byte [] arrHist = getDistHist(i,j);
1085+
1086+
if(arrHist!=null)
1087+
b.append("[" + ArrayUtilsCalc.toString(arrHist) + "]");
1088+
}
1089+
}
1090+
1091+
return b.toString();
1092+
}
1093+
10601094

10611095
public boolean equals(Object o) {
10621096
boolean bEQ=true;

src/main/java/com/actelion/research/chem/descriptor/flexophore/MolDistHistVizHelper.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ public static MolDistHistViz create(List<PPNodeVizMultCoord> liPPNodeVizMultCoor
6464
return molDistHistViz;
6565
}
6666

67+
/**
68+
* Sets the weights in MolDistHistViz. Rule based unification of weight labels for a pharmacophore node.
69+
* @param mdhv
70+
* @param arrWeightLabel Array dimension must equal number of atoms in the molecule in mdhv.
71+
*/
6772
public static void setWeights(MolDistHistViz mdhv, int [] arrWeightLabel){
6873

6974
// The molecule in the descriptor contains the pharmacophore points as additional single atoms.
@@ -75,6 +80,9 @@ public static void setWeights(MolDistHistViz mdhv, int [] arrWeightLabel){
7580
throw new RuntimeException("Weight vector differs in dimension to number of atoms!");
7681
}
7782

83+
//
84+
// Rule based unification of weight labels for a pharmacophore node
85+
//
7886
for (PPNodeViz ppNodeViz : mdhv.getNodes()) {
7987
int [] a = ppNodeViz.getArrayIndexOriginalAtoms();
8088
int [] w = new int[a.length];
@@ -84,7 +92,7 @@ public static void setWeights(MolDistHistViz mdhv, int [] arrWeightLabel){
8492

8593
int maxWeightLabel = ArrayUtils.max(w);
8694

87-
// If label is not high, low is king.
95+
// If label is not high, low is king. Means the standard wight label is overruled.
8896
if(maxWeightLabel< DescriptorWeightsHelper.LABEL_WEIGHT_MANDATORY){
8997
maxWeightLabel = ArrayUtils.min(w);
9098
}

src/main/java/com/actelion/research/chem/descriptor/flexophore/completegraphmatcher/HistogramMatchCalculator.java

+21-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public class HistogramMatchCalculator {
5757
* @param indexDistHist2At2
5858
* @return integral of overlap
5959
*/
60-
public static double getSimilarity(DistHist dh1, int indexDistHist1At1, int indexDistHist1At2, DistHist dh2, int indexDistHist2At1, int indexDistHist2At2){
60+
public static double getFractionOverlapIntegral(DistHist dh1, int indexDistHist1At1, int indexDistHist1At2, DistHist dh2, int indexDistHist2At1, int indexDistHist2At2){
6161
int indexPostStartDistHist1 = dh1.getIndexPosStartForDistHist(indexDistHist1At1, indexDistHist1At2);
6262
int indexPostStartDistHist2 = dh2.getIndexPosStartForDistHist(indexDistHist2At1, indexDistHist2At2);
6363
int n = ConstantsFlexophoreGenerator.BINS_HISTOGRAM;
@@ -73,6 +73,26 @@ public static double getSimilarity(DistHist dh1, int indexDistHist1At1, int inde
7373
double score = sumMin / sumMax;
7474
return score;
7575
}
76+
public static double getFractionOverlappingBins(DistHist dh1, int indexDistHist1At1, int indexDistHist1At2, DistHist dh2, int indexDistHist2At1, int indexDistHist2At2){
77+
int indexPostStartDistHist1 = dh1.getIndexPosStartForDistHist(indexDistHist1At1, indexDistHist1At2);
78+
int indexPostStartDistHist2 = dh2.getIndexPosStartForDistHist(indexDistHist2At1, indexDistHist2At2);
79+
int n = ConstantsFlexophoreGenerator.BINS_HISTOGRAM;
80+
double sumMin = 0;
81+
double sumMax = 0;
82+
83+
double sum1=0;
84+
double sum2=0;
85+
for (int i = 0; i < n; i++) {
86+
int v1 = (dh1.getValueAtAbsolutePosition(indexPostStartDistHist1+i)==0)?0:1;
87+
int v2 = (dh2.getValueAtAbsolutePosition(indexPostStartDistHist2+i)==0)?0:1;
88+
sum1 += v1;
89+
sum2 += v2;
90+
sumMin += Math.min(v1, v2);
91+
sumMax += Math.max(v1, v2);
92+
}
93+
double score = sumMin / Math.min(sum1, sum2);
94+
return score;
95+
}
7696

7797
public static double getPercentageOverlap(DistHist dh1, int indexDistHist1At1, int indexDistHist1At2, DistHist dh2, int indexDistHist2At1, int indexDistHist2At2){
7898
int indexPostStartDistHist1 = dh1.getIndexPosStartForDistHist(indexDistHist1At1, indexDistHist1At2);

src/main/java/com/actelion/research/chem/descriptor/flexophore/completegraphmatcher/ObjectiveBlurFlexophoreHardMatchUncovered.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1156,7 +1156,7 @@ public float getSimilarityHistogram(int indexNode1Query, int indexNode2Query, in
11561156
if(arrSimilarityHistograms[indexHistogramQuery][indexHistogramBase] < 0){
11571157
float similarityHistogram = 0;
11581158
similarityHistogram =
1159-
(float)HistogramMatchCalculator.getSimilarity(
1159+
(float)HistogramMatchCalculator.getFractionOverlappingBins(
11601160
mdhvQueryBlurredHist, indexNode1Query, indexNode2Query, mdhvBaseBlurredHist, indexNode1Base, indexNode2Base);
11611161
arrSimilarityHistograms[indexHistogramQuery][indexHistogramBase]=similarityHistogram;
11621162
}

0 commit comments

Comments
 (0)