Skip to content

Commit fe925c8

Browse files
johnmayegonw
authored andcommitted
Extract out the interfaces for Rgroup queries so we can beter seperate tests. The Rgroup queries need a rethink in my opinion but this will do for now.
1 parent 1fb1a62 commit fe925c8

File tree

10 files changed

+195
-67
lines changed

10 files changed

+195
-67
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/* Copyright (C) 2021 John Mayfield
2+
*
3+
* Contact: cdk-devel@lists.sourceforge.net
4+
*
5+
* This program is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public License
7+
* as published by the Free Software Foundation; either version 2.1
8+
* of the License, or (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* along with this program; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*/
19+
20+
package org.openscience.cdk.isomorphism.matchers;
21+
22+
import org.openscience.cdk.interfaces.IAtom;
23+
import org.openscience.cdk.interfaces.IAtomContainer;
24+
25+
/**
26+
* Represents a single substitute structure in an {@link IRGroupList}. <P>
27+
* The order of attachment points is provided (first and second only, conform
28+
* RGFile spec). This order is relevant when the structure connects to the root
29+
* with more than one bond.
30+
* <P>
31+
* @author John Mayfield
32+
* @see org.openscience.cdk.isomorphism.matchers.IRGroupList
33+
* @see org.openscience.cdk.isomorphism.matchers.IRGroup
34+
*/
35+
public interface IRGroup {
36+
37+
/**
38+
* Get the connection table of atoms/bonds for this Rgroup.
39+
* @return the connection table
40+
*/
41+
IAtomContainer getGroup();
42+
43+
/**
44+
* Get the first attachment point of the RGroup.
45+
* @return the first attachment point
46+
*/
47+
IAtom getFirstAttachmentPoint();
48+
49+
/**
50+
* Get the optional second attachment point of the RGroup.
51+
* @return the second attachment point or null.
52+
*/
53+
IAtom getSecondAttachmentPoint();
54+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/* Copyright (C) 2021 John Mayfield
2+
*
3+
* Contact: cdk-devel@lists.sourceforge.net
4+
*
5+
* This program is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public License
7+
* as published by the Free Software Foundation; either version 2.1
8+
* of the License, or (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* along with this program; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*/
19+
20+
package org.openscience.cdk.isomorphism.matchers;
21+
22+
import java.util.List;
23+
24+
/**
25+
* Represents a list of Rgroup substitutes to be associated with some key in an
26+
* {@link IRGroupQuery}.
27+
*
28+
* @author John Mayfield
29+
*/
30+
public interface IRGroupList {
31+
32+
/**
33+
* Get the Rgroup number, for example R1 => 1.
34+
* @return the Rgroup number
35+
*/
36+
int getRGroupNumber();
37+
38+
/**
39+
* Access the dependant Rgroup number if R1 then R2.
40+
* @return the required Rgroup number.
41+
*/
42+
int getRequiredRGroupNumber();
43+
44+
/**
45+
* Access the list of possible RGroups.
46+
* @return the rgroups.
47+
*/
48+
List<IRGroup> getRGroups();
49+
50+
/**
51+
* Indicates that sites labeled with this Rgroup may only be
52+
* substituted with a member of the Rgroup or with hydrogen.
53+
*/
54+
boolean isRestH();
55+
56+
/**
57+
* Matches the 'occurrence' condition with a provided maximum number of
58+
* RGroup attachments. Returns the valid occurrences (numeric) for these
59+
* two combined. If none found, returns empty list.
60+
* <br>
61+
* Example: if R1 occurs 3 times attached to some root structure, then
62+
* stating "&gt;5" as an occurrence for that RGoupList does not make
63+
* sense: the example R1 can occur 0..3 times. Empty would be returned.<br>
64+
* If the occurence would be &gt;2, then 3 would be returned. Etcetera.
65+
*
66+
* @param maxAttachments number of attachments
67+
* @return valid values by combining a max for R# with the occurrence cond.
68+
*/
69+
List<Integer> matchOccurence(int maxAttachments);
70+
71+
/**
72+
* Occurrence required:
73+
* <UL>
74+
* <LI>n : exactly n ;</LI>
75+
* <LI>n - m : n through m ;</LI>
76+
* <LI>&#62; n : greater than n ;</LI>
77+
* <LI>&#60; n : fewer than n ;</LI>
78+
* <LI>default (blank) is > 0 ;</LI>
79+
* </UL>
80+
* Any non-contradictory combination of the preceding values is also
81+
* allowed; for example "1, 3-7, 9, >11".
82+
*/
83+
String getOccurrence();
84+
}

base/isomorphism/src/main/java/org/openscience/cdk/isomorphism/matchers/IRGroupQuery.java renamed to base/interfaces/src/main/java/org/openscience/cdk/isomorphism/matchers/IRGroupQuery.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,14 @@ public interface IRGroupQuery extends IChemObject {
7979
* @see #getRGroupDefinitions
8080
* @param rGroupDefinitions map with an Integer and an RGroupList (substituent list), the Integer being the R-Group number (1..32).
8181
*/
82-
public void setRGroupDefinitions(Map<Integer, RGroupList> rGroupDefinitions);
82+
public void setRGroupDefinitions(Map<Integer, IRGroupList> rGroupDefinitions);
8383

8484
/**
8585
* Getter for the R-group definitions (substituents).
8686
* @see #setRGroupDefinitions
8787
* @return rGroupDefinitions Map with an Integer and an RGroupList (substituent list), the Integer being the R-Group number (1..32).
8888
*/
89-
public Map<Integer, RGroupList> getRGroupDefinitions();
89+
public Map<Integer, IRGroupList> getRGroupDefinitions();
9090

9191
/**
9292
* Return the total number of atom containers (count the root plus all substituents).

base/isomorphism/src/main/java/org/openscience/cdk/isomorphism/matchers/RGroup.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
* @cdk.keyword R-group
4343
* @author Mark Rijnbeek
4444
*/
45-
public class RGroup {
45+
public class RGroup implements IRGroup {
4646

4747
/**
4848
* Standard label/title to be used for the root atom container.
@@ -66,6 +66,7 @@ public void setFirstAttachmentPoint(IAtom firstAttachmentPoint) {
6666
this.firstAttachmentPoint = firstAttachmentPoint;
6767
}
6868

69+
@Override
6970
public IAtom getFirstAttachmentPoint() {
7071
return firstAttachmentPoint;
7172
}
@@ -74,6 +75,7 @@ public void setSecondAttachmentPoint(IAtom secondAttachmentPoint) {
7475
this.secondAttachmentPoint = secondAttachmentPoint;
7576
}
7677

78+
@Override
7779
public IAtom getSecondAttachmentPoint() {
7880
return secondAttachmentPoint;
7981
}
@@ -82,6 +84,7 @@ public void setGroup(IAtomContainer group) {
8284
this.group = group;
8385
}
8486

87+
@Override
8588
public IAtomContainer getGroup() {
8689
return group;
8790
}

base/isomorphism/src/main/java/org/openscience/cdk/isomorphism/matchers/RGroupList.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
* @cdk.keyword R-group
4545
* @author Mark Rijnbeek
4646
*/
47-
public class RGroupList {
47+
public class RGroupList implements IRGroupList {
4848

4949
/**
5050
* Default value for occurrence field.
@@ -79,7 +79,7 @@ public class RGroupList {
7979
/**
8080
* List of substitute structures.
8181
*/
82-
private List<RGroup> rGroups;
82+
private List<IRGroup> rGroups;
8383

8484
/**
8585
* The rGroup (say B) that is required when this one (say A) exists.<p>
@@ -126,6 +126,7 @@ public void setRGroupNumber(int rGroupNumber) {
126126
this.rGroupNumber = rGroupNumber;
127127
}
128128

129+
@Override
129130
public int getRGroupNumber() {
130131
return rGroupNumber;
131132
}
@@ -134,6 +135,7 @@ public void setRestH(boolean restH) {
134135
this.restH = restH;
135136
}
136137

138+
@Override
137139
public boolean isRestH() {
138140
return restH;
139141
}
@@ -142,22 +144,25 @@ public void setRequiredRGroupNumber(int rGroupNumberImplicated) {
142144
this.requiredRGroupNumber = rGroupNumberImplicated;
143145
}
144146

147+
@Override
145148
public int getRequiredRGroupNumber() {
146149
return requiredRGroupNumber;
147150
}
148151

149-
public void setRGroups(List<RGroup> rGroups) {
152+
public void setRGroups(List<IRGroup> rGroups) {
150153
this.rGroups = rGroups;
151154
}
152155

153-
public List<RGroup> getRGroups() {
156+
@Override
157+
public List<IRGroup> getRGroups() {
154158
return rGroups;
155159
}
156160

157161
/**
158162
* Returns the occurrence value.
159163
* @return occurrence
160164
*/
165+
@Override
161166
public String getOccurrence() {
162167
return occurrence;
163168
}
@@ -259,6 +264,7 @@ private static boolean match(String regExp, String userInput) {
259264
* @param maxAttachments number of attachments
260265
* @return valid values by combining a max for R# with the occurrence cond.
261266
*/
267+
@Override
262268
public List<Integer> matchOccurence(int maxAttachments) {
263269

264270
List<Integer> validValues = new ArrayList<Integer>();

base/isomorphism/src/main/java/org/openscience/cdk/isomorphism/matchers/RGroupQuery.java

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public class RGroupQuery extends QueryChemObject implements IChemObject, Seriali
8787
* Rgroup definitions, each a list of possible substitutes for the
8888
* given R number.
8989
*/
90-
private Map<Integer, RGroupList> rGroupDefinitions;
90+
private Map<Integer, IRGroupList> rGroupDefinitions;
9191

9292
/**
9393
* For each Rgroup Atom there may be a map containing (number,bond),
@@ -212,7 +212,7 @@ public List<IAtomContainer> getAllConfigurations() throws CDKException {
212212
// R# group is present (1) or absent (0).
213213
List<Integer[]> distributions = new ArrayList<Integer[]>();
214214

215-
List<List<RGroup>> substitutes = new ArrayList<List<RGroup>>();
215+
List<List<IRGroup>> substitutes = new ArrayList<>();
216216

217217
//Valid occurrences for each R# group
218218
List<List<Integer>> occurrences = new ArrayList<List<Integer>>();
@@ -251,7 +251,7 @@ public List<IAtomContainer> getAllConfigurations() throws CDKException {
251251
* for {@link #getAllConfigurations()}.
252252
*/
253253
private void findConfigurationsRecursively(List<Integer> rGroupNumbers, List<List<Integer>> occurrences,
254-
List<Integer> occurIndexes, List<Integer[]> distributions, List<List<RGroup>> substitutes, int level,
254+
List<Integer> occurIndexes, List<Integer[]> distributions, List<List<IRGroup>> substitutes, int level,
255255
List<IAtomContainer> result) throws CDKException {
256256

257257
if (level == rGroupNumbers.size()) {
@@ -273,8 +273,8 @@ private void findConfigurationsRecursively(List<Integer> rGroupNumbers, List<Lis
273273
int rNum = rGroupNumbers.get(rgpIdx);
274274
int pos = 0;
275275

276-
List<RGroup> mapped = substitutes.get(rgpIdx);
277-
for (RGroup substitute : mapped) {
276+
List<IRGroup> mapped = substitutes.get(rgpIdx);
277+
for (IRGroup substitute : mapped) {
278278
IAtom rAtom = this.getRgroupQueryAtoms(rNum).get(pos);
279279
if (substitute != null) {
280280

@@ -397,12 +397,12 @@ && isValidRgroupQueryLabel(((IPseudoAtom) cloneBond.getEnd()).getLabel()))
397397
for (Integer[] distribution : rgrpDistributions) {
398398
distributions.set(level, distribution);
399399

400-
RGroup[] mapping = new RGroup[distribution.length];
401-
List<List<RGroup>> mappedSubstitutes = new ArrayList<List<RGroup>>();
400+
IRGroup[] mapping = new IRGroup[distribution.length];
401+
List<List<IRGroup>> mappedSubstitutes = new ArrayList<>();
402402
mapSubstitutes(this.getRGroupDefinitions().get(rGroupNumbers.get(level)), 0, distribution, mapping,
403403
mappedSubstitutes);
404404

405-
for (List<RGroup> mappings : mappedSubstitutes) {
405+
for (List<IRGroup> mappings : mappedSubstitutes) {
406406
substitutes.set(level, mappings);
407407
findConfigurationsRecursively(rGroupNumbers, occurrences, occurIndexes, distributions,
408408
substitutes, level + 1, result);
@@ -465,19 +465,19 @@ private void findDistributions(int occur, Integer[] candidate, List<Integer[]> d
465465
* @param mapping
466466
* @param result
467467
*/
468-
private void mapSubstitutes(RGroupList rgpList, int listOffset, Integer[] distribution, RGroup[] mapping,
469-
List<List<RGroup>> result) {
468+
private void mapSubstitutes(IRGroupList rgpList, int listOffset, Integer[] distribution, IRGroup[] mapping,
469+
List<List<IRGroup>> result) {
470470
if (listOffset == distribution.length) {
471-
List<RGroup> mapped = new ArrayList<RGroup>();
472-
for (RGroup rgrp : mapping)
471+
List<IRGroup> mapped = new ArrayList<>();
472+
for (IRGroup rgrp : mapping)
473473
mapped.add(rgrp);
474474
result.add(mapped);
475475
} else {
476476
if (distribution[listOffset] == 0) {
477477
mapping[listOffset] = null;
478478
mapSubstitutes(rgpList, listOffset + 1, distribution, mapping, result);
479479
} else {
480-
for (RGroup rgrp : rgpList.getRGroups()) {
480+
for (IRGroup rgrp : rgpList.getRGroups()) {
481481
mapping[listOffset] = rgrp;
482482
mapSubstitutes(rgpList, listOffset + 1, distribution, mapping, result);
483483
}
@@ -547,7 +547,7 @@ private boolean checkIfThenConditionsMet(List<Integer> rGroupNumbers, List<Integ
547547
for (int inner = 0; inner < rGroupNumbers.size(); inner++) {
548548
int rgroupNum2 = rGroupNumbers.get(inner);
549549
if (!allZeroArray(distributions.get(inner))) {
550-
RGroupList rgrpList = rGroupDefinitions.get(rgroupNum2);
550+
IRGroupList rgrpList = rGroupDefinitions.get(rgroupNum2);
551551
if (rgrpList.getRequiredRGroupNumber() == rgroupNum) {
552552
logger.info(" Rejecting >> all 0 for " + rgroupNum + " but requirement found from "
553553
+ rgrpList.getRGroupNumber());
@@ -565,7 +565,7 @@ public int getAtomContainerCount() {
565565
int retVal = 0;
566566
if (this.rootStructure != null) retVal++;
567567
for (Integer r : rGroupDefinitions.keySet()) {
568-
for (RGroup rgrp : rGroupDefinitions.get(r).getRGroups()) {
568+
for (IRGroup rgrp : rGroupDefinitions.get(r).getRGroups()) {
569569
if (rgrp.getGroup() != null) {
570570
retVal++;
571571
}
@@ -578,7 +578,7 @@ public int getAtomContainerCount() {
578578
public List<IAtomContainer> getSubstituents() {
579579
List<IAtomContainer> substitutes = new ArrayList<IAtomContainer>();
580580
for (Integer r : rGroupDefinitions.keySet()) {
581-
for (RGroup rgrp : rGroupDefinitions.get(r).getRGroups()) {
581+
for (IRGroup rgrp : rGroupDefinitions.get(r).getRGroups()) {
582582
IAtomContainer subst = rgrp.getGroup();
583583
if (subst != null) substitutes.add(subst);
584584
}
@@ -607,12 +607,12 @@ public Map<IAtom, Map<Integer, IBond>> getRootAttachmentPoints() {
607607
}
608608

609609
@Override
610-
public void setRGroupDefinitions(Map<Integer, RGroupList> rGroupDefinitions) {
610+
public void setRGroupDefinitions(Map<Integer, IRGroupList> rGroupDefinitions) {
611611
this.rGroupDefinitions = rGroupDefinitions;
612612
}
613613

614614
@Override
615-
public Map<Integer, RGroupList> getRGroupDefinitions() {
615+
public Map<Integer, IRGroupList> getRGroupDefinitions() {
616616
return rGroupDefinitions;
617617
}
618618
}

0 commit comments

Comments
 (0)